Clipboard paste

pull/1/head
DJh2o2 2023-04-13 11:32:37 +07:00
parent aec5c8fcae
commit 717a42f63b
6 changed files with 376 additions and 391 deletions

@ -20,27 +20,28 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Blazorise.Bootstrap" Version="1.2.1" />
<PackageReference Include="Blazorise.Components" Version="1.2.1" />
<PackageReference Include="Blazorise.DataGrid" Version="1.2.1" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.2.1" />
<PackageReference Include="Blazorise.Icons.Material" Version="1.2.1" />
<PackageReference Include="Blazorise.LoadingIndicator" Version="1.2.1" />
<PackageReference Include="Blazorise.Material" Version="1.2.1" />
<PackageReference Include="Blazorise.Bootstrap" Version="1.2.2" />
<PackageReference Include="Blazorise.Components" Version="1.2.2" />
<PackageReference Include="Blazorise.DataGrid" Version="1.2.2" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.2.2" />
<PackageReference Include="Blazorise.Icons.Material" Version="1.2.2" />
<PackageReference Include="Blazorise.LoadingIndicator" Version="1.2.2" />
<PackageReference Include="Blazorise.Material" Version="1.2.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="8.0.0-preview.3.23177.8" />
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.0-preview.1.23112.2" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="8.0.0-preview.1.23112.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.0-preview.1.23111.4">
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.0-preview.3.23177.8" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="8.0.0-preview.3.23177.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.0-preview.3.23174.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.0-preview.1.23111.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.0-preview.1.23111.4">
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.0-preview.3.23174.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.0-preview.3.23174.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.17.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.0-preview.1.23117.2" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.18.1" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.0-preview.3.23206.5" />
<PackageReference Include="MySql.EntityFrameworkCore" Version="7.0.0" />
<PackageReference Include="MySqlConnector" Version="2.3.0-beta.1" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="7.0.0" />

@ -2,306 +2,304 @@
@using Gremlin_BlazorServer.Services
@using Gremlin_BlazorServer.Data.EntityClasses
@using System.Globalization
@using System.Security.Claims;
@using System.Text;
@inject GenericController GenericController
@inject NavigationManager NavigationManager
@inject QuoteHandling QuoteHandling
@inject HostingService HostingService
@inject IJSRuntime JsRuntime
@inject ILoadingIndicatorService ApplicationLoadingIndicatorService
@* @inject ILoadingIndicatorService ApplicationLoadingIndicatorService *@
<AuthorizeView>
<Authorized>
<Div Margin="Margin.Is3"
Border="Border.Dark.OnAll"
Padding="Padding.Is3"
style="box-shadow: 10px 10px #343A40">
<Heading Size="HeadingSize.Is5">Recipient</Heading>
<Paragraph>
<DataGrid TItem="Contact"
Data="@contacts"
SelectedRow="@selectedContact"
SelectedRowChanged="@OnSelectedContactChanged"
Bordered Hoverable Filterable Striped ShowPager Responsive Sortable>
<DataGridCommandColumn/>
<DataGridColumn Field="@nameof(Contact.ContactId)" Caption="ContactId" Sortable Filterable/>
<DataGridColumn Field="@nameof(Contact.AccountId)" Caption="AccountId" Sortable Filterable/>
<DataGridColumn Field="@nameof(Contact.FirstName)" Caption="FirstName" Sortable Filterable/>
<DataGridColumn Field="@nameof(Contact.LastName)" Caption="LastName" Sortable Filterable/>
<DataGridColumn Field="@nameof(Contact.Gender)" Caption="Gender" Sortable Filterable/>
<DataGridColumn Field="@nameof(Contact.EMail)" Caption="EMail" Sortable Filterable/>
<DataGridColumn Field="@nameof(Contact.PhoneNumber)" Caption="PhoneNumber" Sortable Filterable/>
<DataGridColumn Field="@nameof(Contact.SapContactNumber)" Caption="SAPContactNumber" Sortable Filterable/>
</DataGrid>
</Paragraph>
</Div>
@if (quote is not null)
{
<Div Margin="Margin.Is3"
Border="Border.Dark.OnAll"
Padding="Padding.Is3"
style="box-shadow: 10px 10px #343A40">
<Authorized>
<Div Margin="Margin.Is3"
Border="Border.Dark.OnAll"
Padding="Padding.Is3"
style="box-shadow: 10px 10px #343A40">
<Heading Size="HeadingSize.Is5">Quote Details</Heading>
<Paragraph>
<Row>
<Column ColumnSize="ColumnSize.Is4">
<Field>
<FieldLabel ColumnSize="ColumnSize.Is4">Angebotsname</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">
<TextEdit Text="@quote.Description" TextChanged="@OnDescriptionChanged"/>
</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is4">Angebotsnummer</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">
<TextEdit Text="@quote.QuotationNumber" TextChanged="@OnQuotationNumberChanged"/>
</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is4">Angebotspfad</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">
<TextEdit ReadOnly Text="@quote.Path"/>"
</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is4">Gewährleistung (Monate)</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">
<TextEdit Text="@quote.Warranty.ToString()" TextChanged="@OnWarrantyChanged"/>
</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is4">Angebotsgültigkeit (Tage)</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">
<TextEdit Text="@quote.ValidFor.ToString()" TextChanged="@OnValidForChanged"/>
</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is4">Mehrwertsteuer (%)</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">
<TextEdit Text="@quote.Vat.ToString(CultureInfo.CurrentCulture)" TextChanged="@OnVATChanged"/>
</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is4">Versandkosten (%)</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">
<TextEdit Text="@quote.Freight.ToString(CultureInfo.CurrentCulture)"/>
</FieldBody>
</Field>
</Column>
<Heading Size="HeadingSize.Is5">Recipient</Heading>
<Paragraph>
<DataGrid TItem="Contact"
Data="@contacts"
SelectedRow="@selectedContact"
SelectedRowChanged="@SelectedContactChanged"
Bordered Hoverable Filterable Striped ShowPager Responsive Sortable>
@if (quote?.Recipient?.Account is not null)
{
<Column ColumnSize="ColumnSize.Is3">
<Field>
<FieldLabel ColumnSize="ColumnSize.Is4">FirstName</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">@quote.Recipient.FirstName</FieldBody>
</Field>
<Field >
<FieldLabel ColumnSize="ColumnSize.Is4">LastName</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">@quote.Recipient.LastName</FieldBody>
</Field>
<Field >
<FieldLabel ColumnSize="ColumnSize.Is4">AccountName</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">@quote.Recipient.Account.AccountName</FieldBody>
</Field>
<Field >
<FieldLabel ColumnSize="ColumnSize.Is4">Street</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">@quote.Recipient.Account.Street</FieldBody>
</Field>
<Field >
<FieldLabel ColumnSize="ColumnSize.Is4">Zip</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">@quote.Recipient.Account.Zip.ToString()</FieldBody>
</Field>
<Field >
<FieldLabel ColumnSize="ColumnSize.Is4">City</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">@quote.Recipient.Account.City</FieldBody>
</Field>
</Column>
}
<DataGridCommandColumn/>
<DataGridColumn Field="@nameof(Contact.ContactId)" Caption="ContactId" Sortable Filterable/>
<DataGridColumn Field="@nameof(Contact.AccountId)" Caption="AccountId" Sortable Filterable/>
<DataGridColumn Field="@nameof(Contact.FirstName)" Caption="FirstName" Sortable Filterable/>
<DataGridColumn Field="@nameof(Contact.LastName)" Caption="LastName" Sortable Filterable/>
<DataGridColumn Field="@nameof(Contact.Gender)" Caption="Gender" Sortable Filterable/>
<DataGridColumn Field="@nameof(Contact.EMail)" Caption="EMail" Sortable Filterable/>
<DataGridColumn Field="@nameof(Contact.PhoneNumber)" Caption="PhoneNumber" Sortable Filterable/>
<DataGridColumn Field="@nameof(Contact.SapContactNumber)" Caption="SAPContactNumber" Sortable Filterable/>
</DataGrid>
</Paragraph>
</Div>
<Column ColumnSize="ColumnSize.Is2">
<Check TValue="bool" Checked="@quote.IsPriceInformation" CheckedChanged="@OnIsPriceInformationChanged">Preisinformation</Check>
<Check TValue="bool" Checked="@quote.ShowBrutto" CheckedChanged="@OnShowBruttoChanged">Bruttopreise anzeigen</Check>
<Check TValue="bool" Checked="@quote.ShowSinglePrices" CheckedChanged="@OnShowSinglePricesChanged">Einzelpreise ausweisen</Check>
<Check TValue="bool" Checked="@quote.ShowDiscounts" CheckedChanged="@OnShowDiscountsChanged">Discounts ausweisen</Check>
</Column>
<Div Margin="Margin.Is3"
Border="Border.Dark.OnAll"
Padding="Padding.Is3"
style="box-shadow: 10px 10px #343A40">
<Column ColumnSize="ColumnSize.Is3">
<Field>
<FieldLabel ColumnSize="ColumnSize.Is4">Listenpreis netto</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">
<TextEdit ReadOnly Text="@quote.TotalListprice.ToString("C", CultureInfo.CurrentCulture)"></TextEdit>
</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is4">Summe netto</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">
<TextEdit ReadOnly Text="@quote.TotalNet.ToString("C", CultureInfo.CurrentCulture)"></TextEdit>
</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is4">Versandkosten</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">
<TextEdit ReadOnly Text="@quote.TotalFreightOnly.ToString("C", CultureInfo.CurrentCulture)"></TextEdit>
</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is4">Gesamtsumme netto</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">
<TextEdit ReadOnly Text="@quote.TotalFreight.ToString("C", CultureInfo.CurrentCulture)"></TextEdit>
</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is4">Mehrwertsteuer</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">
<TextEdit ReadOnly Text="@quote.TotalVat.ToString("C", CultureInfo.CurrentCulture)"></TextEdit>
</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is4">Gesamtsumme brutto</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">
<TextEdit ReadOnly Text="@quote.TotalGross.ToString("C", CultureInfo.CurrentCulture)"></TextEdit>
</FieldBody>
</Field>
</Column>
</Row>
</Paragraph>
</Div>
}
<Heading Size="HeadingSize.Is5">Quote Details</Heading>
<Paragraph>
<Row>
<Column ColumnSize="ColumnSize.Is4">
<Field>
<FieldLabel ColumnSize="ColumnSize.Is4">Angebotsname</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">
<TextEdit Text="@quote.Description" TextChanged="@OnDescriptionChanged"/>
</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is4">Angebotsnummer</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">
<TextEdit Text="@quote.QuotationNumber" TextChanged="@OnQuotationNumberChanged"/>
</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is4">Angebotspfad</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">
<TextEdit ReadOnly Text="@quote.Path"/>"
</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is4">Gewährleistung (Monate)</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">
<TextEdit Text="@quote.Warranty.ToString()" TextChanged="@OnWarrantyChanged"/>
</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is4">Angebotsgültigkeit (Tage)</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">
<TextEdit Text="@quote.ValidFor.ToString()" TextChanged="@OnValidForChanged"/>
</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is4">Mehrwertsteuer (%)</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">
<TextEdit Text="@quote.Vat.ToString(CultureInfo.CurrentCulture)" TextChanged="@OnVATChanged"/>
</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is4">Versandkosten (%)</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">
<TextEdit Text="@quote.Freight.ToString(CultureInfo.CurrentCulture)"/>
</FieldBody>
</Field>
</Column>
@if (quote?.LineItems is not null) {
<Div Margin="Margin.Is3"
Border="Border.Dark.OnAll"
Padding="Padding.Is3"
style="box-shadow: 10px 10px #343A40">
<Heading Size="HeadingSize.Is5">LineItems</Heading>
<Paragraph>
<DataGrid TItem="LineItem"
Data="@quote.LineItems"
SelectedRow="@selectedLineItem"
SelectedRowChanged="@OnSelectedLineItemChanged"
Bordered Hoverable Striped ShowPager Responsive>
<DataGridCommandColumn/>
<DataGridColumn Field="@nameof(LineItem.Position)" Caption="Position" />
<DataGridColumn Field="@nameof(LineItem.Amount)" Caption="Amount" />
<DataGridColumn Field="@nameof(LineItem.ProductNumber)" Caption="ProductNumber"/>
<DataGridColumn Field="@nameof(LineItem.OptionNumber)" Caption="OptionNumber"/>
<DataGridColumn Field="@nameof(LineItem.SapShortDescription)" Caption="SapShortDescription" />
<DataGridColumn Field="@nameof(LineItem.ListPrice)" DisplayFormat="{0:C}" DisplayFormatProvider=cultureInfo Caption="ListPrice" />
<DataGridColumn Field="@nameof(LineItem.TotalDiscount)" DisplayFormat="{0:n2}%" Caption="TotalDiscount" />
<DataGridColumn Field="@nameof(LineItem.Total)" DisplayFormat="{0:C}" DisplayFormatProvider=cultureInfo Caption="Total"/>
</DataGrid>
</Paragraph>
</Div>
@if (selectedLineItem?.Product?.CustomDescription is not null) {
<Div Margin="Margin.Is3"
Border="Border.Dark.OnAll"
Padding="Padding.Is3"
style="box-shadow: 10px 10px #343A40">
<Heading Size="HeadingSize.Is5">CustomDescriptions</Heading>
<Paragraph>
@if (quote?.Recipient?.Account is not null) {
<Column ColumnSize="ColumnSize.Is3">
<Field>
<FieldLabel ColumnSize="ColumnSize.Is1">ProductNumber</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is11">@selectedLineItem.Product.CustomDescription.ProductNumber</FieldBody>
<FieldLabel ColumnSize="ColumnSize.Is4">FirstName</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">@quote.Recipient.FirstName</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is1">OptionNumber</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is11">@selectedLineItem.OptionNumber</FieldBody>
<Field >
<FieldLabel ColumnSize="ColumnSize.Is4">LastName</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">@quote.Recipient.LastName</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is1">Heading</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is11">@selectedLineItem.Product.CustomDescription.Heading</FieldBody>
<Field >
<FieldLabel ColumnSize="ColumnSize.Is4">AccountName</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">@quote.Recipient.Account.AccountName</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is1">CoverletterText</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is11">@selectedLineItem.Product.CustomDescription.CoverletterText</FieldBody>
<Field >
<FieldLabel ColumnSize="ColumnSize.Is4">Street</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">@quote.Recipient.Account.Street</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is1">DescriptionText</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is11">@selectedLineItem.Product.CustomDescription.DescriptionText</FieldBody>
<Field >
<FieldLabel ColumnSize="ColumnSize.Is4">Zip</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">@quote.Recipient.Account.Zip.ToString()</FieldBody>
</Field>
<Field >
<FieldLabel ColumnSize="ColumnSize.Is4">City</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">@quote.Recipient.Account.City</FieldBody>
</Field>
</Paragraph>
</Div>
</Column>
}
}
@if (quote is {LineItems: null }) {
<Div Margin="Margin.Is3"
Border="Border.Dark.OnAll"
Padding="Padding.Is3"
style="box-shadow: 10px 10px #343A40">
<Column ColumnSize="ColumnSize.Is2">
<Check TValue="bool" Checked="@quote.IsPriceInformation" CheckedChanged="@OnIsPriceInformationChanged">Preisinformation</Check>
<Check TValue="bool" Checked="@quote.ShowBrutto" CheckedChanged="@OnShowBruttoChanged">Bruttopreise anzeigen</Check>
<Check TValue="bool" Checked="@quote.ShowSinglePrices" CheckedChanged="@OnShowSinglePricesChanged">Einzelpreise ausweisen</Check>
<Check TValue="bool" Checked="@quote.ShowDiscounts" CheckedChanged="@OnShowDiscountsChanged">Discounts ausweisen</Check>
</Column>
<Heading Size="HeadingSize.Is5">Upload PriceSurfer Quote </Heading>
<Paragraph>
<Field>
<FieldLabel>Please select PriceSurfer quote as TSV</FieldLabel>
<FileEdit Filter=".tsv" Changed="@SelectQuoteOnChanged" Written="@SelectQuoteOnWritten" Progressed="@SelectQuoteOnProgressed"/>
</Field>
</Paragraph>
</Div>
}
<Column ColumnSize="ColumnSize.Is3">
<Field>
<FieldLabel ColumnSize="ColumnSize.Is4">Listenpreis netto</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">
<TextEdit ReadOnly Text="@quote.TotalListprice.ToString("C", CultureInfo.CurrentCulture)"></TextEdit>
</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is4">Summe netto</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">
<TextEdit ReadOnly Text="@quote.TotalNet.ToString("C", CultureInfo.CurrentCulture)"></TextEdit>
</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is4">Versandkosten</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">
<TextEdit ReadOnly Text="@quote.TotalFreightOnly.ToString("C", CultureInfo.CurrentCulture)"></TextEdit>
</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is4">Gesamtsumme netto</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">
<TextEdit ReadOnly Text="@quote.TotalFreight.ToString("C", CultureInfo.CurrentCulture)"></TextEdit>
</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is4">Mehrwertsteuer</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">
<TextEdit ReadOnly Text="@quote.TotalVat.ToString("C", CultureInfo.CurrentCulture)"></TextEdit>
</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is4">Gesamtsumme brutto</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is6">
<TextEdit ReadOnly Text="@quote.TotalGross.ToString("C", CultureInfo.CurrentCulture)"></TextEdit>
</FieldBody>
</Field>
</Column>
</Row>
</Paragraph>
</Div>
<Div Margin="Margin.Is3"
Border="Border.Dark.OnAll"
Padding="Padding.Is3"
style="box-shadow: 10px 10px #343A40">
<Heading Size="HeadingSize.Is5">Create Quote</Heading>
@if (quote?.LineItems is not null) {
<Div Margin="Margin.Is3"
Border="Border.Dark.OnAll"
Padding="Padding.Is3"
style="box-shadow: 10px 10px #343A40">
<Heading Size="HeadingSize.Is5">LineItems</Heading>
<Paragraph>
<DataGrid TItem="LineItem"
Data="@quote.LineItems"
SelectedRow="@selectedLineItem"
SelectedRowChanged="@OnSelectedLineItemChanged"
Bordered Hoverable Striped ShowPager Responsive>
<DataGridCommandColumn/>
<DataGridColumn Field="@nameof(LineItem.Position)" Caption="Position"/>
<DataGridColumn Field="@nameof(LineItem.Amount)" Caption="Amount"/>
<DataGridColumn Field="@nameof(LineItem.ProductNumber)" Caption="ProductNumber"/>
<DataGridColumn Field="@nameof(LineItem.OptionNumber)" Caption="OptionNumber"/>
<DataGridColumn Field="@nameof(LineItem.SapShortDescription)" Caption="SapShortDescription"/>
<DataGridColumn Field="@nameof(LineItem.ListPrice)" DisplayFormat="{0:C}" DisplayFormatProvider=cultureInfo Caption="ListPrice"/>
<DataGridColumn Field="@nameof(LineItem.TotalDiscount)" DisplayFormat="{0:n2}%" Caption="TotalDiscount"/>
<DataGridColumn Field="@nameof(LineItem.Total)" DisplayFormat="{0:C}" DisplayFormatProvider=cultureInfo Caption="Total"/>
</DataGrid>
</Paragraph>
</Div>
@if (selectedLineItem?.Product?.CustomDescription is not null) {
<Div Margin="Margin.Is3"
Border="Border.Dark.OnAll"
Padding="Padding.Is3"
style="box-shadow: 10px 10px #343A40">
<Heading Size="HeadingSize.Is5">CustomDescriptions</Heading>
<Paragraph>
<Button Color="Color.Primary" Disabled="@lineItemsNotReady" Clicked="@OnCreateTex" Loading="@isCreatingTex">Create Tex from Quote</Button>
<Button Color="Color.Secondary" Disabled="@texNotReady" Clicked="@OnCreatePdf" Loading="@isCreatingPdf">Create Pdf from Tex</Button>
<Button Color="Color.Secondary" Disabled="@pdfNotReady" Clicked="@OnOpenPdfApp">Open Pdf with App</Button>
<Button Color="Color.Secondary" Disabled="@pdfNotReady" Clicked="@OnOpenPdfNewTab">Open Pdf in Tab</Button>
<Button Color="Color.Success" Disabled="@pdfNotReady" Clicked="@OnSave">Save</Button>
<Button Color="Color.Danger" Clicked="@OnCancel">Cancel</Button>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is1">ProductNumber</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is11">@selectedLineItem.Product.CustomDescription.ProductNumber</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is1">OptionNumber</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is11">@selectedLineItem.OptionNumber</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is1">Heading</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is11">@selectedLineItem.Product.CustomDescription.Heading</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is1">CoverletterText</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is11">@selectedLineItem.Product.CustomDescription.CoverletterText</FieldBody>
</Field>
<Field>
<FieldLabel ColumnSize="ColumnSize.Is1">DescriptionText</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is11">@selectedLineItem.Product.CustomDescription.DescriptionText</FieldBody>
</Field>
</Paragraph>
</Div>
}
}
@if (!pdfNotReady && url != null && debug) {
<Div Margin="Margin.Is3"
Border="Border.Dark.OnAll"
Padding="Padding.Is3"
style="box-shadow: 10px 10px #343A40">
@if (quote is {LineItems: null }) {
<Div Margin="Margin.Is3"
Border="Border.Dark.OnAll"
Padding="Padding.Is3"
style="box-shadow: 10px 10px #343A40">
<Heading Size="HeadingSize.Is5">PDF</Heading>
<Paragraph>
<iframe src="/quotes/@url" style="width:50%;height:600px;"></iframe>
</Paragraph>
</Div>
}
<Heading Size="HeadingSize.Is5">Load PriceSurfer quote</Heading>
<Paragraph>
<Button Color="Color.Primary" Clicked="@GetClipboardTextAsync">Paste from Clipboard</Button>
</Paragraph>
<Paragraph>
<Field>
<FieldLabel>Please select PriceSurfer quote as TSV</FieldLabel>
<FileEdit Filter=".tsv" Changed="@SelectQuoteOnChanged" Written="@SelectQuoteOnWritten" Progressed="@SelectQuoteOnProgressed"/>
</Field>
</Paragraph>
</Div>
}
@if (quote != null && quote.Tex != null && debug) {
<Div Margin="Margin.Is3"
Border="Border.Dark.OnAll"
Padding="Padding.Is3"
style="box-shadow: 10px 10px #343A40">
<Div Margin="Margin.Is3"
Border="Border.Dark.OnAll"
Padding="Padding.Is3"
style="box-shadow: 10px 10px #343A40">
<Heading Size="HeadingSize.Is5">Tex</Heading>
<Paragraph>
<MemoEdit ReadOnly Size="Size.Small" Autosize @bind-Text="@quote.Tex" />
</Paragraph>
</Div>
}
<Heading Size="HeadingSize.Is5">Create Quote</Heading>
<Paragraph>
<Button Color="Color.Primary" Disabled="@lineItemsNotReady" Clicked="@OnCreateTex" Loading="@isCreatingTex">Create Tex from Quote</Button>
<Button Color="Color.Secondary" Disabled="@texNotReady" Clicked="@OnCreatePdf" Loading="@isCreatingPdf">Create Pdf from Tex</Button>
<Button Color="Color.Secondary" Disabled="@pdfNotReady" Clicked="@OnOpenPdfApp">Open Pdf with App</Button>
<Button Color="Color.Secondary" Disabled="@pdfNotReady" Clicked="@OnOpenPdfNewTab">Open Pdf in Tab</Button>
<Button Color="Color.Success" Disabled="@pdfNotReady" Clicked="@OnSave">Save</Button>
<Button Color="Color.Danger" Clicked="@OnCancel">Cancel</Button>
</Paragraph>
</Div>
</Authorized>
@if (!pdfNotReady && url != null && debug) {
<Div Margin="Margin.Is3"
Border="Border.Dark.OnAll"
Padding="Padding.Is3"
style="box-shadow: 10px 10px #343A40">
<NotAuthorized>
<Div Margin="Margin.Is3"
Border="Border.Dark.OnAll"
Padding="Padding.Is3"
style="box-shadow: 10px 10px #343A40">
<Heading Size="HeadingSize.Is5">PDF</Heading>
<Paragraph>
<iframe src="/quotes/@url" style="width:50%;height:600px;"></iframe>
</Paragraph>
</Div>
}
<Heading Size="HeadingSize.Is3">Authentication Failure!</Heading>
<Paragraph>You're not signed in. Please click on the upper right to either register or log in.</Paragraph>
</Div>
</NotAuthorized>
</AuthorizeView>
@if (quote != null && quote.Tex != null && debug) {
<Div Margin="Margin.Is3"
Border="Border.Dark.OnAll"
Padding="Padding.Is3"
style="box-shadow: 10px 10px #343A40">
<Heading Size="HeadingSize.Is5">Tex</Heading>
<Paragraph>
<MemoEdit ReadOnly Size="Size.Small" Autosize @bind-Text="@quote.Tex"/>
</Paragraph>
</Div>
}
</Authorized>
<NotAuthorized>
<Div Margin="Margin.Is3"
Border="Border.Dark.OnAll"
Padding="Padding.Is3"
style="box-shadow: 10px 10px #343A40">
<Heading Size="HeadingSize.Is3">Authentication Failure!</Heading>
<Paragraph>You're not signed in. Please click on the upper right to either register or log in.</Paragraph>
</Div>
</NotAuthorized>
</AuthorizeView>

@ -1,4 +1,3 @@
using System.Diagnostics;
using System.Globalization;
using System.Security.Claims;
using System.Text;
@ -19,18 +18,18 @@ public partial class QuoteAdd {
private bool isCreatingPdf;
private bool isCreatingTex;
private bool lineItemsNotReady = true;
private CustomDescription? newCustomDescription;
private static CustomDescription newCustomDescription;
private bool pdfNotReady = true;
private Quote quote = new();
private Contact? selectedContact;
private LineItem? selectedLineItem;
private List<CustomDescription>? suggestedCustomDescriptions;
// private List<CustomDescription>? suggestedCustomDescriptions;
private bool texNotReady = true;
private string? url;
[CascadingParameter] private Task<AuthenticationState>? AuthenticationStateTask { get; set; }
[Inject] public IModalService? ModalService { get; set; }
[Inject] public static IModalService ModalService { get; set; }
public Task ShowCustomDescriptionModal() {
public static Task ShowCustomDescriptionModal(List<CustomDescription> suggestedCustomDescriptions) {
return ModalService.Show<CustomDescriptionModal>(builder => {
builder.Add(parameter => parameter.CustomDescription, newCustomDescription);
builder.Add(parameter => parameter.SuggestedCustomDescriptions, suggestedCustomDescriptions);
@ -44,7 +43,7 @@ public partial class QuoteAdd {
contacts = await GenericController.GetAllAsync<Contact>();
selectedContact = contacts?.FirstOrDefault();
if (selectedContact is not null)
await OnSelectedContactChanged(selectedContact);
await SelectedContactChanged(selectedContact);
SalesRep newSalesRep = new() {
LastName = "Woitschetzki",
@ -83,37 +82,8 @@ public partial class QuoteAdd {
_ = stream.Seek(0, SeekOrigin.Begin);
using StreamReader reader = new(stream);
string fileContent = await reader.ReadToEndAsync();
quote = QuoteHandling.ReadLineItems(quote, fileContent);
if (quote.Recipient?.Account?.AccountName is not null) quote = HostingService.SetPath(quote);
if (quote.LineItems is null) return;
FileService.WriteQuoteToTsv(fileContent, quote);
//TODO Load all relevant CustomDescriptions upfront
foreach (LineItem lineItem in quote.LineItems) {
newCustomDescription = await GenericController.GetAsync<CustomDescription>(newCustomDescription => newCustomDescription.ProductNumber.Equals(lineItem.ProductNumber, StringComparison.Ordinal) && newCustomDescription.OptionNumber.Equals(lineItem.OptionNumber, StringComparison.Ordinal));
if (newCustomDescription is null) {
Console.WriteLine($"Keine CustomDescription für {lineItem.ProductNumber}#{lineItem.OptionNumber} verfügbar!");
suggestedCustomDescriptions = await SuggestCustomDescriptions(lineItem);
newCustomDescription = new() { ProductNumber = lineItem.ProductNumber, OptionNumber = lineItem.OptionNumber, Heading = lineItem.SapShortDescription, DescriptionText = lineItem.SapLongDescription };
//Show windows to edit new cD
await ShowCustomDescriptionModal();
//TODO need to wait for modal!
//Insert new CustomDescription to db
newCustomDescription.AccountId = 1;
_ = await GenericController.InsertAsync(newCustomDescription);
}
lineItem.Product = await GenericController.GetAsync<Product>(p => p.ProductNumber.Equals(lineItem.ProductNumber) && p.OptionNumber.Equals(lineItem.OptionNumber));
if (lineItem.Product is null) return;
lineItem.ProductId = lineItem.Product.ProductId;
lineItem.Product.CustomDescription = await GenericController.GetAsync<CustomDescription>(cD => cD.ProductNumber.Equals(lineItem.ProductNumber) && cD.OptionNumber.Equals(lineItem.OptionNumber));
lineItem.Quote = quote;
lineItem.QuoteId = lineItem.Quote.QuoteId;
}
quote = await QuoteHandling.GenerateQuoteFromString(quote, fileContent);
}
}
catch (Exception exc) {
@ -125,18 +95,6 @@ public partial class QuoteAdd {
}
}
private async Task<List<CustomDescription>?> SuggestCustomDescriptions(LineItem lineItem) {
//IList<CustomDescription>? fromProductNumber = await genericController.GetAllAsync<CustomDescription>(cD => cD.ProductNumber.Equals(lineItem.ProductNumber, StringComparison.Ordinal));
IList<CustomDescription>? fromOptionNumber = new List<CustomDescription>();
if (lineItem.OptionNumber != "")
fromOptionNumber = await GenericController.GetAllAsync<CustomDescription>(cD => cD.OptionNumber.Equals(lineItem.OptionNumber, StringComparison.Ordinal));
//if (fromOptionNumber == null && fromProductNumber == null) return null;
//if (fromOptionNumber == null) return fromProductNumber.ToList();
//if (fromProductNumber == null) return fromOptionNumber.ToList();
//return fromProductNumber.Union(fromOptionNumber).ToList();
return fromOptionNumber.ToList();
}
private static void SelectQuoteOnWritten(FileWrittenEventArgs e) {
Console.WriteLine($"File: {e.File.Name} Position: {e.Position} Data: {Convert.ToBase64String(e.Data)}");
}
@ -145,7 +103,7 @@ public partial class QuoteAdd {
Console.WriteLine($"File: {e.File.Name} Progress: {e.Percentage}");
}
private async Task OnSelectedContactChanged(Contact newSelectedContact) {
private async Task SelectedContactChanged(Contact newSelectedContact) {
quote.Recipient = await GenericController.GetAsync<Contact>(c => c.ContactId.Equals(newSelectedContact.ContactId));
if (quote.Recipient is not null)
@ -193,55 +151,31 @@ public partial class QuoteAdd {
}
}
private void OnOpenPdfApp() {
PdfService.OpenPdfWithOkular(quote);
}
private void OnOpenPdfApp() => PdfService.OpenPdfWithOkular(quote);
private async Task OnOpenPdfNewTab() {
await JsRuntime.InvokeVoidAsync("OpenNewTab", $"quotes/{url}");
}
private async Task OnOpenPdfNewTab() => await JsRuntime.InvokeVoidAsync("OpenNewTab", $"quotes/{url}");
private void OnDescriptionChanged(string description) {
quote.Description = description;
}
private void OnDescriptionChanged(string description) => quote.Description = description;
private void OnQuotationNumberChanged(string quotationNumber) {
quote.QuotationNumber = quotationNumber;
}
private void OnQuotationNumberChanged(string quotationNumber) => quote.QuotationNumber = quotationNumber;
private void OnValidForChanged(string validFor) {
quote.ValidFor = byte.Parse(validFor);
}
private void OnValidForChanged(string validFor) => quote.ValidFor = byte.Parse(validFor);
private void OnVATChanged(string vat) {
quote.Vat = float.Parse(vat);
}
private void OnVATChanged(string vat) => quote.Vat = float.Parse(vat);
private void OnIsPriceInformationChanged(bool isPriceInformation) {
quote.IsPriceInformation = isPriceInformation;
}
private void OnIsPriceInformationChanged(bool isPriceInformation) => quote.IsPriceInformation = isPriceInformation;
private void OnShowBruttoChanged(bool onShowBrutto) {
quote.ShowBrutto = onShowBrutto;
}
private void OnShowBruttoChanged(bool onShowBrutto) => quote.ShowBrutto = onShowBrutto;
private void OnShowDiscountsChanged(bool showDiscount) {
quote.ShowDiscounts = showDiscount;
}
private void OnShowDiscountsChanged(bool showDiscount) => quote.ShowDiscounts = showDiscount;
private void OnShowSinglePricesChanged(bool showSinglePrices) {
quote.ShowSinglePrices = showSinglePrices;
}
private void OnShowSinglePricesChanged(bool showSinglePrices) => quote.ShowSinglePrices = showSinglePrices;
private void OnSelectedLineItemChanged(LineItem _selectedLineItem) {
selectedLineItem = _selectedLineItem;
}
private void OnSelectedLineItemChanged(LineItem newSelectedLineItem) => selectedLineItem = newSelectedLineItem;
private void OnWarrantyChanged(string warranty) {
quote.Warranty = int.Parse(warranty);
}
private void OnWarrantyChanged(string warranty) => quote.Warranty = int.Parse(warranty);
private void OnCancel() {
NavigationManager.NavigateTo("Quotes/QuoteIndex");
}
private void OnCancel() => NavigationManager.NavigateTo("Quotes/QuoteIndex");
private async Task<string> GetClipboardTextAsync() => await JsRuntime.InvokeAsync<string>("navigator.clipboard.readText");
}

@ -22,6 +22,7 @@ builder.Services.AddServerSideBlazor();
builder.Services.AddScoped<GremlinDb>();
builder.Services.AddScoped<GenericController>();
builder.Services.AddScoped<HostingService>();
builder.Services.AddScoped<QuoteHandling>();
builder.Services.AddScoped<GenericImporter>();
builder.Services.AddBlazorise(options => { options.Immediate = true; })

@ -2,14 +2,11 @@ using Gremlin_BlazorServer.Data.EntityClasses;
namespace Gremlin_BlazorServer.Services;
internal class HostingService
public class HostingService
{
private readonly IWebHostEnvironment _hostingEnvironment;
private readonly IWebHostEnvironment hostingEnvironment;
public HostingService(IWebHostEnvironment hostingEnvironment)
{
_hostingEnvironment = hostingEnvironment;
}
public HostingService(IWebHostEnvironment newHostingEnvironment) => hostingEnvironment = newHostingEnvironment;
public Quote SetPath(Quote quote)
{
@ -23,7 +20,7 @@ internal class HostingService
string description = quote.Description.Replace(" ", "_");
quote.Path = Path.Combine(
_hostingEnvironment.WebRootPath,
hostingEnvironment.WebRootPath,
"quotes",
accountName,
$"{DateTime.Today.Year}-{DateTime.Today.Month}-{quote.Recipient?.LastName}-{description}"

@ -1,12 +1,14 @@
using System.Globalization;
using System.Text;
using Gremlin_BlazorServer.Data.EntityClasses;
using Gremlin_BlazorServer.Pages.Quotes;
namespace Gremlin_BlazorServer.Services;
public static class QuoteHandling {
private static GenericController genericController = new();
public class QuoteHandling {
private static readonly GenericController genericController = new();
private readonly IWebHostEnvironment hostingEnvironment;
public static async Task<StringBuilder?> CreateTexAsync(Quote quote) {
StringBuilder? texString = await TexService.CreateTex(quote);
if (texString is null) return null;
@ -17,7 +19,7 @@ public static class QuoteHandling {
//FromWindowsGremlin
public static Quote ReadLineItems(Quote quote, string clipboard) {
private Quote ReadLineItems(Quote quote, string clipboard) {
try {
quote = ResetTotals(quote);
@ -53,7 +55,7 @@ public static class QuoteHandling {
}
}
private static List<LineItem> ReadLineItemsFromClipboard(string clipboard) {
private List<LineItem> ReadLineItemsFromClipboard(string clipboard) {
//Zeilen aufteilen
IEnumerable<string> clipboardLines = clipboard.Split(Environment.NewLine.ToCharArray());
List<string[]> clipboardList = (from clipboardLine in clipboardLines where clipboardLine != "" select clipboardLine.Split('\t')).ToList();
@ -61,7 +63,7 @@ public static class QuoteHandling {
return lineItems;
}
private static async Task<List<LineItem>> ParseClipboardList(List<string[]> lineItemStrings) {
private async Task<List<LineItem>> ParseClipboardList(List<string[]> lineItemStrings) {
List<LineItem> lineItems = new();
CultureInfo cultureInfoUs = new("en-US");
@ -98,16 +100,16 @@ public static class QuoteHandling {
return lineItems;
}
private static byte CheckForAcademic(Account account) {
private byte CheckForAcademic(Account account) {
return account.AccountType?.AccountTypeCode == null ? (byte)60 : (byte)(account.AccountType.AccountTypeCode.StartsWith("N") ? 90 : 60);
}
private static decimal GetFreight(decimal net, decimal freight) {
private decimal GetFreight(decimal net, decimal freight) {
decimal freightNet = net * freight / 100;
return freightNet < 3000 ? freightNet : 3000;
}
private static Quote CalculateTotals(Quote quote) {
private Quote CalculateTotals(Quote quote) {
quote.TotalFreightOnly = GetFreight(quote.TotalNet, quote.Freight);
quote.TotalFreight = quote.TotalNet + quote.TotalFreightOnly;
quote.TotalVat = quote.TotalFreight * Convert.ToDecimal(quote.Vat) / 100;
@ -115,7 +117,7 @@ public static class QuoteHandling {
return quote;
}
private static Quote ResetTotals(Quote quote) {
private Quote ResetTotals(Quote quote) {
quote.TotalListprice = 0;
quote.TotalNet = 0;
quote.TotalFreightOnly = 0;
@ -126,7 +128,7 @@ public static class QuoteHandling {
return quote;
}
private static decimal GetTotal(Quote quote, string type) {
private decimal GetTotal(Quote quote, string type) {
decimal total = 0;
if (quote.LineItems == null) return total;
@ -148,8 +150,8 @@ public static class QuoteHandling {
return total;
}
private static bool DoesContains(Quote quote, string type) {
if (quote.LineItems == null) return false;
private bool DoesContains(Quote quote, string type) {
if (quote.LineItems is null) return false;
foreach (LineItem lineItem in quote.LineItems)
switch (type) {
@ -171,4 +173,56 @@ public static class QuoteHandling {
return false;
}
public async Task<Quote> GenerateQuoteFromString(Quote quote, string fileContent) {
HostingService hostingService = new(hostingEnvironment);
quote = ReadLineItems(quote, fileContent);
if (quote.Recipient?.Account?.AccountName is not null) quote = hostingService.SetPath(quote);
if (quote.LineItems is null) return quote;
FileService.WriteQuoteToTsv(fileContent, quote);
//TODO Load all relevant CustomDescriptions upfront
foreach (LineItem lineItem in quote.LineItems) {
CustomDescription newCustomDescription = await genericController.GetAsync<CustomDescription>(newCustomDescription => newCustomDescription.ProductNumber.Equals(lineItem.ProductNumber, StringComparison.Ordinal) && newCustomDescription.OptionNumber.Equals(lineItem.OptionNumber, StringComparison.Ordinal));
if (newCustomDescription is null) {
Console.WriteLine($"Keine CustomDescription für {lineItem.ProductNumber}#{lineItem.OptionNumber} verfügbar!");
List<CustomDescription>? suggestedCustomDescriptions = await SuggestCustomDescriptions(lineItem);
newCustomDescription = new() {
ProductNumber = lineItem.ProductNumber,
OptionNumber = lineItem.OptionNumber,
Heading = lineItem.SapShortDescription,
DescriptionText = lineItem.SapLongDescription
};
//Show windows to edit new cD
await QuoteAdd.ShowCustomDescriptionModal(suggestedCustomDescriptions);
//TODO need to wait for modal!
//Insert new CustomDescription to db
newCustomDescription.AccountId = 1;
_ = await genericController.InsertAsync(newCustomDescription);
}
lineItem.Product = await genericController.GetAsync<Product>(p => p.ProductNumber.Equals(lineItem.ProductNumber) && p.OptionNumber.Equals(lineItem.OptionNumber));
if (lineItem.Product is null) return quote;
lineItem.ProductId = lineItem.Product.ProductId;
lineItem.Product.CustomDescription = await genericController.GetAsync<CustomDescription>(cD => cD.ProductNumber.Equals(lineItem.ProductNumber) && cD.OptionNumber.Equals(lineItem.OptionNumber));
lineItem.Quote = quote;
lineItem.QuoteId = lineItem.Quote.QuoteId;
}
return quote;
}
private static async Task<List<CustomDescription>?> SuggestCustomDescriptions(LineItem lineItem) {
//IList<CustomDescription>? fromProductNumber = await genericController.GetAllAsync<CustomDescription>(cD => cD.ProductNumber.Equals(lineItem.ProductNumber, StringComparison.Ordinal));
IList<CustomDescription>? fromOptionNumber = new List<CustomDescription>();
if (lineItem.OptionNumber != "")
fromOptionNumber = await genericController.GetAllAsync<CustomDescription>(cD => cD.OptionNumber.Equals(lineItem.OptionNumber, StringComparison.Ordinal));
//if (fromOptionNumber == null && fromProductNumber == null) return null;
//if (fromOptionNumber == null) return fromProductNumber.ToList();
//if (fromProductNumber == null) return fromOptionNumber.ToList();
//return fromProductNumber.Union(fromOptionNumber).ToList();
return fromOptionNumber.ToList();
}
}