using System;
using System.ComponentModel.DataAnnotations;
// This is the model for one row in the database table.
namespace BlazorPurchaseOrders.Data
{
public class POHeader
{
[Required]
public int POHeaderID { get; set; }
[Required]
public int POHeaderOrderNumber { get; set; }
[Required]
public DateTime POHeaderOrderDate { get; set; }
[Required]
public int POHeaderSupplierID { get; set; }
[StringLength(50, ErrorMessage = "'Address' has a maximum length of 50 characters.")]
public string POHeaderSupplierAddress1 { get; set; }
[StringLength(50, ErrorMessage = "'Address' has a maximum length of 50 characters.")]
public string POHeaderSupplierAddress2 { get; set; }
[StringLength(50, ErrorMessage = "'Address' has a maximum length of 50 characters.")]
public string POHeaderSupplierAddress3 { get; set; }
[StringLength(10, ErrorMessage = "'Post Code' has a maximum length of 10 characters.")]
public string POHeaderSupplierPostCode { get; set; }
[StringLength(256, ErrorMessage = "'Email' has a maximum length of 256 characters.")]
[EmailAddress(ErrorMessage = "Invalid Email Address format.")]
public string POHeaderSupplierEmail { get; set; }
[StringLength(450)]
public string POHeaderRequestedBy { get; set; }
[Required]
public bool POHeaderIsArchived { get; set; }
public decimal POHeaderOrderTotal { get; }
}
}
POLine.cs
using System;
using System.ComponentModel.DataAnnotations;
// This is the model for one row in the database table.
namespace BlazorPurchaseOrders.Data
{
public class POLine
{
[Required]
public int POLineID { get; set; }
[Required]
public int POLineHeaderID { get; set; }
[Required]
public int POLineProductID { get; set; }
[Required(ErrorMessage = "Product Description is compulsory.")]
[StringLength(50, MinimumLength = 2, ErrorMessage = "Product Description must be between 2 and 20 characters.")]
public string POLineProductDescription { get; set; }
[Required]
public decimal POLineProductQuantity { get; set; }
[Required]
public decimal POLineProductUnitPrice { get; set; }
[Required]
public decimal POLineTaxRate { get; set; }
//The folowing are not saved to database - just for the DataGrid
public decimal? POLineNetPrice { get; set; }
public decimal POLineTaxAmount { get; set; }
public decimal POLineGrossPrice { get; set; }
public string POLineProductCode { get; set; }
//POLIneTaxID is not saved to the database, but is needed for the Tax Rate drop-down list
//It would be more usual to save the TaxID to POLine in the database, but because
//tax rate percentages might change in future for a particular 'rate' we don't want
//historic tax amounts to be recalculated if re-displayed in the future.
public int POLineTaxID { get; set; }
}
}
ProductService.cs
using Dapper;
using Microsoft.Data.SqlClient;
using System;
using System.Collections.Generic;
using System.Data;
using System.Threading.Tasks;
namespace BlazorPurchaseOrders.Data
{
public class ProductService : IProductService
{
// Database connection
private readonly SqlConnectionConfiguration _configuration;
public ProductService(SqlConnectionConfiguration configuration)
{
_configuration = configuration;
}
// Add (create) a Product table row (SQL Insert)
// This only works if you're already created the stored procedure.
public async Task<int> ProductInsert(
string ProductCode,
string ProductDescription,
decimal ProductUnitPrice,
Int32 ProductSupplierID
)
{
int Success = 0;
var parameters = new DynamicParameters();
parameters.Add("ProductCode", ProductCode, DbType.String);
parameters.Add("ProductDescription", ProductDescription, DbType.String);
parameters.Add("ProductUnitPrice", ProductUnitPrice, DbType.Decimal);
parameters.Add("ProductSupplierID", ProductSupplierID, DbType.Int32);
parameters.Add("@ReturnValue", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);
using (var conn = new SqlConnection(_configuration.Value))
{
// Stored procedure method
await conn.ExecuteAsync("spProduct_Insert", parameters, commandType: CommandType.StoredProcedure);
Success = parameters.Get<int>("@ReturnValue");
}
return Success;
}
// Get a list of product rows (SQL Select)
// This only works if you're already created the stored procedure.
public async Task<IEnumerable<Product>> ProductList()
{
IEnumerable<Product> products;
using (var conn = new SqlConnection(_configuration.Value))
{
products = await conn.QueryAsync<Product>("spProduct_List", commandType: CommandType.StoredProcedure);
}
return products;
}
// Get list of products based on their SupplierID (SQL Select)
public async Task<IEnumerable<Product>> ProductListBySupplier(int @SupplierID)
{
IEnumerable<Product> products;
var parameters = new DynamicParameters();
parameters.Add("@SupplierID", SupplierID, DbType.Int32);
using (var conn = new SqlConnection(_configuration.Value))
{
products = await conn.QueryAsync<Product>("spProduct_ListBySupplier", parameters, commandType: CommandType.StoredProcedure);
}
return products;
}
// Get one product based on its ProductID (SQL Select)
// This only works if you're already created the stored procedure.
public async Task<Product> Product_GetOne(int @ProductID)
{
Product product = new Product();
var parameters = new DynamicParameters();
parameters.Add("@ProductID", ProductID, DbType.Int32);
using (var conn = new SqlConnection(_configuration.Value))
{
product = await conn.QueryFirstOrDefaultAsync<Product>("spProduct_GetOne", parameters, commandType: CommandType.StoredProcedure);
}
return product;
}
// Update one Product row based on its ProductID (SQL Update)
// This only works if you're already created the stored procedure.
public async Task<int> ProductUpdate(
int ProductID,
string ProductCode,
string ProductDescription,
decimal ProductUnitPrice,
Int32 ProductSupplierID,
bool ProductIsArchived
)
{
int Success = 0;
var parameters = new DynamicParameters();
parameters.Add("ProductID", ProductID, DbType.Int32);
parameters.Add("ProductCode", ProductCode, DbType.String);
parameters.Add("ProductDescription", ProductDescription, DbType.String);
parameters.Add("ProductUnitPrice", ProductUnitPrice, DbType.Decimal);
parameters.Add("ProductSupplierID", ProductSupplierID, DbType.Int32);
parameters.Add("ProductIsArchived", ProductIsArchived, DbType.Boolean);
parameters.Add("@ReturnValue", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);
using (var conn = new SqlConnection(_configuration.Value))
{
await conn.ExecuteAsync("spProduct_Update", parameters, commandType: CommandType.StoredProcedure);
Success = parameters.Get<int>
("@ReturnValue");
}
return Success;
}
}
}
IProductService.cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace BlazorPurchaseOrders.Data
{
// Each item below provides an interface to a method in ProductServices.cs
public interface IProductService
{
Task<int> ProductInsert(
string ProductCode,
string ProductDescription,
decimal ProductUnitPrice,
Int32 ProductSupplierID);
Task<IEnumerable<Product>> ProductList();
Task<IEnumerable<Product>> ProductListBySupplier(int SupplierID);
Task<Product> Product_GetOne(int ProductID);
Task<int> ProductUpdate(
int ProductID,
string ProductCode,
string ProductDescription,
decimal ProductUnitPrice,
Int32 ProductSupplierID,
bool ProductIsArchived
);
}
}
PurchaseOrderPage.cs
@page "/purchaseorder/{POHeaderID:int}"
@using BlazorPurchaseOrders.Data
@inject NavigationManager NavigationManager
@inject ISupplierService SupplierService
@inject IPOHeaderService POHeaderService
@inject IProductService ProductService
@inject ITaxService TaxService
@using Microsoft.AspNetCore.Components.Authorization
@inject AuthenticationStateProvider AuthenticationStateProvider
@using System
@using System.Collections.Generic
<h3>@pagetitle</h3>
<EditForm Model="@orderaddedit" OnValidSubmit="@OrderSave">
<DataAnnotationsValidator />
<div class="grid-container">
<div class="grid-child left-column">
<SfDropDownList DataSource="@supplier"
TItem="Supplier"
TValue="int"
Text="SupplierID"
@bind-Value="orderaddedit.POHeaderSupplierID"
FloatLabelType="@FloatLabelType.Auto"
Placeholder="Select a Supplier"
Enabled="@supplierEnabled">
<DropDownListFieldSettings Text="SupplierName" Value="SupplierID"></DropDownListFieldSettings>
<DropDownListEvents TItem="Supplier" TValue="int" ValueChange="OnChangeSupplier"></DropDownListEvents>
</SfDropDownList>
<SfTextBox Enabled="true" Placeholder="Address"
FloatLabelType="@FloatLabelType.Always"
@bind-Value="orderaddedit.POHeaderSupplierAddress1"></SfTextBox>
<ValidationMessage For="@(() => orderaddedit.POHeaderSupplierAddress1)" />
<SfTextBox Enabled="true" Placeholder=""
FloatLabelType="@FloatLabelType.Never"
@bind-Value="orderaddedit.POHeaderSupplierAddress2"></SfTextBox>
<ValidationMessage For="@(() => orderaddedit.POHeaderSupplierAddress2)" />
<SfTextBox Enabled="true" Placeholder=""
FloatLabelType="@FloatLabelType.Never"
@bind-Value="orderaddedit.POHeaderSupplierAddress3"></SfTextBox>
<ValidationMessage For="@(() => orderaddedit.POHeaderSupplierAddress3)" />
<SfTextBox Enabled="true" Placeholder="Post Code"
FloatLabelType="@FloatLabelType.Never"
@bind-Value="orderaddedit.POHeaderSupplierPostCode"></SfTextBox>
<ValidationMessage For="@(() => orderaddedit.POHeaderSupplierPostCode)" />
<SfTextBox Enabled="true" Placeholder="Email"
FloatLabelType="@FloatLabelType.Auto"
@bind-Value="orderaddedit.POHeaderSupplierEmail"></SfTextBox>
<ValidationMessage For="@(() => orderaddedit.POHeaderSupplierEmail)" />
</div>
<div class="grid-child right-column">
<SfNumericTextBox Enabled="false" Placeholder="Order No"
FloatLabelType="@FloatLabelType.Always"
ShowSpinButton="false"
@bind-Value="orderaddedit.POHeaderOrderNumber"></SfNumericTextBox>
<SfDatePicker TValue="DateTime"
Placeholder='Order Date'
FloatLabelType="@FloatLabelType.Auto"
@bind-Value="orderaddedit.POHeaderOrderDate"></SfDatePicker>
<SfTextBox Enabled="false" Placeholder="Requested by"
FloatLabelType="@FloatLabelType.Always"
@bind-Value="orderaddedit.POHeaderRequestedBy"></SfTextBox>
</div>
</div>
<br />
<SfGrid @ref="OrderLinesGrid"
DataSource="@orderLines"
Toolbar="@Toolbaritems"
AllowResizing="true">
<GridColumns>
<GridColumn Field="@nameof(POLine.POLineProductCode)"
HeaderText="Product"
TextAlign="@TextAlign.Left"
Width="20">
</GridColumn>
<GridColumn Field="@nameof(POLine.POLineProductDescription)"
HeaderText="Description"
TextAlign="@TextAlign.Left"
Width="30">
</GridColumn>
<GridColumn Field="@nameof(POLine.POLineProductQuantity)"
HeaderText="Quantity"
TextAlign="@TextAlign.Right"
Format="n0"
Width="10">
</GridColumn>
<GridColumn Field="@nameof(POLine.POLineProductUnitPrice)"
HeaderText="Unit Price"
TextAlign="@TextAlign.Right"
Format="C2"
Width="10">
</GridColumn>
<GridColumn Field="@nameof(POLine.POLineNetPrice)"
HeaderText="Net Price"
TextAlign="@TextAlign.Right"
Format="C2"
Width="10">
</GridColumn>
<GridColumn Field="@nameof(POLine.POLineTaxRate)"
HeaderText="Tax Rate"
TextAlign="@TextAlign.Right"
Format="p2"
Width="10">
</GridColumn>
<GridColumn Field="@nameof(POLine.POLineTaxAmount)"
HeaderText="Tax"
TextAlign="@TextAlign.Right"
Format="C2"
Width="10">
</GridColumn>
<GridColumn Field="@nameof(POLine.POLineGrossPrice)"
HeaderText="Total"
TextAlign="@TextAlign.Right"
Format="C2"
Width="10">
</GridColumn>
</GridColumns>
<GridAggregates>
<GridAggregate>
<GridAggregateColumns>
<GridAggregateColumn Field=@nameof(POLine.POLineNetPrice) Type="AggregateType.Sum" Format="C2">
<FooterTemplate Context="NetContext">
@{
var aggregate = NetContext as AggregateTemplateContext;
<div>
<p>@aggregate.Sum</p>
</div>
}
</FooterTemplate>
</GridAggregateColumn>
<GridAggregateColumn Field=@nameof(POLine.POLineTaxAmount) Type="AggregateType.Sum" Format="C2">
<FooterTemplate Context="TaxContext">
@{
var aggregate = TaxContext as AggregateTemplateContext;
<div>
<p>@aggregate.Sum</p>
</div>
}
</FooterTemplate>
</GridAggregateColumn>
<GridAggregateColumn Field=@nameof(POLine.POLineGrossPrice) Type="AggregateType.Sum" Format="C2">
<FooterTemplate Context="GrossContext">
@{
var aggregate = GrossContext as AggregateTemplateContext;
<div>
<p>@aggregate.Sum</p>
</div>
}
</FooterTemplate>
</GridAggregateColumn>
</GridAggregateColumns>
</GridAggregate>
</GridAggregates>
<GridEvents OnToolbarClick="ToolbarClickHandler" TValue="POLine"></GridEvents>
</SfGrid>
<br />
<div class="e-footer-content">
<div class="button-container">
<button type="submit" class="e-btn e-normal e-primary">Save</button>
<button type="button" class="e-btn e-normal" @onclick="@Cancel">Cancel</button>
</div>
</div>
</EditForm>
<SfDialog @ref="DialogAddEditOrderLine" IsModal="true" Width="600px" ShowCloseIcon="true" Visible="false">
<DialogTemplates>
<Header> Add Order Line </Header>
</DialogTemplates>
<EditForm Model="@addeditOrderLine" OnValidSubmit="@OrderLineSave">
<DataAnnotationsValidator />
<div class=flex-container>
<SfDropDownList DataSource="@product"
TItem="Product"
TValue="int"
Text="ProductID"
@bind-Value="addeditOrderLine.POLineProductID"
FloatLabelType="@FloatLabelType.Always"
Placeholder="Select a Product"
Enabled="true">
<DropDownListFieldSettings Text="ProductCode" Value="ProductID"></DropDownListFieldSettings>
<DropDownListEvents TItem="Product" TValue="int" OnValueSelect="OnChangeProduct"></DropDownListEvents>
</SfDropDownList>
</div>
<div class=flex-container>
<SfTextBox Enabled="true" Placeholder="Product Description"
FloatLabelType="@FloatLabelType.Always"
@bind-Value="addeditOrderLine.POLineProductDescription"></SfTextBox>
</div>
<div class=flex-container>
<ValidationMessage For="@(() => addeditOrderLine.POLineProductDescription)" />
</div><div class=flex-container>
<SfNumericTextBox Enabled="true" Placeholder="Quantity"
FloatLabelType="@FloatLabelType.Always"
ShowSpinButton="false"
Format="n0"
EnableRtl="true"
@bind-Value="addeditOrderLine.POLineProductQuantity"
@onfocusout='@POLineCalc'>
</SfNumericTextBox>
<SfNumericTextBox Enabled="true" Placeholder="Unit Price"
FloatLabelType="@FloatLabelType.Always"
ShowSpinButton="false"
Format="c2"
EnableRtl="true"
@bind-Value="addeditOrderLine.POLineProductUnitPrice"
@onfocusout='@POLineCalc'>
</SfNumericTextBox>
<SfNumericTextBox Enabled="false" Placeholder="Net Price"
FloatLabelType="@FloatLabelType.Always"
ShowSpinButton="false"
Format="c2"
EnableRtl="true"
@bind-Value="addeditOrderLine.POLineNetPrice">
</SfNumericTextBox>
</div>
<div class=flex-container>
<SfDropDownList DataSource="@tax"
TItem="Tax"
TValue="int"
Text="TaxID"
@bind-Value="addeditOrderLine.POLineTaxID"
FloatLabelType="@FloatLabelType.Always"
Placeholder="Tax Rate"
Enabled="true">
<DropDownListFieldSettings Text="TaxDescription" Value="TaxID"></DropDownListFieldSettings>
<DropDownListEvents TItem="Tax" TValue="int" OnValueSelect="OnChangeTax"></DropDownListEvents>
</SfDropDownList>
<SfNumericTextBox Enabled="false" Placeholder="Tax Rate %"
FloatLabelType="@FloatLabelType.Always"
ShowSpinButton="false"
Format="p2"
EnableRtl="true"
@bind-Value="addeditOrderLine.POLineTaxRate">
</SfNumericTextBox>
<SfNumericTextBox Enabled="false" Placeholder="Tax Amount"
FloatLabelType="@FloatLabelType.Always"
ShowSpinButton="false"
Format="c2"
EnableRtl="true"
@bind-Value="addeditOrderLine.POLineTaxAmount">
</SfNumericTextBox>
</div>
<div class=flex-container>
<SfNumericTextBox Enabled="false" Placeholder="Total Price"
FloatLabelType="@FloatLabelType.Always"
ShowSpinButton="false"
Format="c2"
EnableRtl="true"
@bind-Value="addeditOrderLine.POLineGrossPrice">
</SfNumericTextBox>
</div>
<br />
<div class="e-footer-content">
<div class="button-container">
<button type="button" class="e-btn e-normal" @onclick="@CloseDialog">Cancel</button>
<button type="submit" class="e-btn e-normal e-primary">Save</button>
</div>
</div>
</EditForm>
</SfDialog>
<WarningPage @ref="Warning" WarningHeaderMessage="@WarningHeaderMessage" WarningContentMessage="@WarningContentMessage" />
<style>
.grid-container {
display: grid;
max-width: 900px; /* Maximum width of the whole container - in this case both columns */
grid-template-columns: 1fr 1fr; /* Relative width of each column (1fr 1fr is equivalent to, say, 33fr 33fr */
grid-gap: 75px; /* size of the gap between columns */
}
.flex-container {
display: flex;
flex-direction: row; /* Causes tab to move along row and then onto following row */
justify-content: space-evenly; /* Equal space left and right margin and between elements */
margin: 10px; /* This appears to be vertical margin between rows */
column-gap: 10px; /* Tgap betwen columns */
}
</style>
@code {
POHeader orderaddedit = new POHeader();
IEnumerable<Supplier> supplier;
IEnumerable<Product> product;
IEnumerable<Tax> tax;
string pagetitle = "";
private string UserName;
SfGrid<POLine> OrderLinesGrid;
public List<POLine> orderLines = new List<POLine>();
private List<ItemModel> Toolbaritems = new List<ItemModel>();
SfDialog DialogAddEditOrderLine;
public POLine addeditOrderLine = new POLine();
WarningPage Warning;
string WarningHeaderMessage = "";
string WarningContentMessage = "";
public bool supplierEnabled { get; set; } = true;
[Parameter]
public int POHeaderID { get; set; }
//Executes on page open, sets headings and gets data in the case of edit
protected override async Task OnInitializedAsync()
{
supplier = await SupplierService.SupplierList();
orderaddedit.POHeaderOrderDate = DateTime.Now;
//product = await ProductService.ProductList();
tax = await TaxService.TaxList();
if (POHeaderID == 0)
{
pagetitle = "Add an Order";
}
else
{
pagetitle = "Edit an Order";
}
//Get user if logged in and populate the 'Requested by' column
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
if (user.Identity.IsAuthenticated)
{
UserName = user.Identity.Name;
}
else
{
UserName = "The user is NOT authenticated.";
}
orderaddedit.POHeaderRequestedBy = UserName;
Toolbaritems.Add(new ItemModel() { Text = "Add", TooltipText = "Add a new order line", PrefixIcon = "e-add" });
Toolbaritems.Add(new ItemModel() { Text = "Edit", TooltipText = "Edit selected order line", PrefixIcon = "e-edit" });
Toolbaritems.Add(new ItemModel() { Text = "Delete", TooltipText = "Delete selected order line", PrefixIcon = "e-delete" });
}
private async Task OnChangeSupplier(Syncfusion.Blazor.DropDowns.ChangeEventArgs<int, Supplier> args)
{
this.orderaddedit.POHeaderSupplierAddress1 = args.ItemData.SupplierAddress1;
this.orderaddedit.POHeaderSupplierAddress2 = args.ItemData.SupplierAddress2;
this.orderaddedit.POHeaderSupplierAddress3 = args.ItemData.SupplierAddress3;
this.orderaddedit.POHeaderSupplierPostCode = args.ItemData.SupplierPostCode;
this.orderaddedit.POHeaderSupplierEmail = args.ItemData.SupplierEmail;
//Refresh product to select only those products for this supplier (and products with null suppliers)
product = await ProductService.ProductListBySupplier(args.ItemData.SupplierID);
}
// Executes OnValidSubmit of EditForm above
protected async Task OrderSave()
{
if (POHeaderID == 0)
{
//Save the record
bool Successs = await POHeaderService.POHeaderInsert(orderaddedit);
NavigationManager.NavigateTo("/");
}
else
{
NavigationManager.NavigateTo("/");
}
}
//Executes if user clicks the Cancel button.
void Cancel()
{
NavigationManager.NavigateTo("/");
}
public async Task ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args)
{
if (args.Item.Text == "Add")
{
//Code for adding goes here
//Check that a supplier has been selected from the drop-down list
if (orderaddedit.POHeaderSupplierID == 0)
{
WarningHeaderMessage = "Warning!";
WarningContentMessage = "Please Select a Supplier before adding order lines.";
Warning.OpenDialog();
}
else
{
addeditOrderLine = new POLine(); // Ensures a blank form when adding
addeditOrderLine.POLineNetPrice = 0;
addeditOrderLine.POLineTaxID = 0;
addeditOrderLine.POLineProductID = 0;
await this.DialogAddEditOrderLine.Show();
}
}
if (args.Item.Text == "Edit")
{
//Code for adding goes here
}
if (args.Item.Text == "Delete")
{
//Code for adding goes here
}
}
private void OrderLineSave()
{
if (addeditOrderLine.POLineID == 0)
{
//Code to save order line goes here
//Check that a product has been selected from the drop-down list
if (addeditOrderLine.POLineProductCode == null || addeditOrderLine.POLineProductCode == "")
{
WarningHeaderMessage = "Warning!";
WarningContentMessage = "Please select a Product.";
Warning.OpenDialog();
}
//And check that a tax rate has been selected from the drop-down list
else if (addeditOrderLine.POLineTaxID == 0)
{
WarningHeaderMessage = "Warning!";
WarningContentMessage = "Please select a Tax Rate.";
Warning.OpenDialog();
}
else
{
orderLines.Add(new POLine
{
POLineHeaderID = 0,
POLineProductID = addeditOrderLine.POLineProductID,
POLineProductCode = addeditOrderLine.POLineProductCode,
POLineProductDescription = addeditOrderLine.POLineProductDescription,
POLineProductQuantity = addeditOrderLine.POLineProductQuantity,
POLineProductUnitPrice = addeditOrderLine.POLineProductUnitPrice,
POLineNetPrice = addeditOrderLine.POLineNetPrice,
POLineTaxRate = addeditOrderLine.POLineTaxRate,
POLineTaxAmount = addeditOrderLine.POLineTaxAmount,
POLineGrossPrice = addeditOrderLine.POLineGrossPrice
});
OrderLinesGrid.Refresh();
StateHasChanged(); //<----- THIS IS ABSOLUTELY ESSENTIAL
//addeditOrderLine = new POLine(); //<----- THIS gives errors (nulls)
addeditOrderLine.POLineProductID = 0;
addeditOrderLine.POLineProductCode = "";
addeditOrderLine.POLineProductDescription = "";
addeditOrderLine.POLineProductQuantity = 0;
addeditOrderLine.POLineProductUnitPrice = 0;
addeditOrderLine.POLineNetPrice = 0;
addeditOrderLine.POLineTaxID = 0;
addeditOrderLine.POLineTaxRate = 0;
addeditOrderLine.POLineTaxAmount = 0;
addeditOrderLine.POLineGrossPrice = 0;
//We now have order lines, so prevent user from changing the supplier
supplierEnabled = false;
}
}
}
private async Task CloseDialog()
{
await this.DialogAddEditOrderLine.Hide();
}
private void OnChangeProduct(Syncfusion.Blazor.DropDowns.SelectEventArgs<Product> args)
{
this.addeditOrderLine.POLineProductCode = args.ItemData.ProductCode;
this.addeditOrderLine.POLineProductDescription = args.ItemData.ProductDescription;
this.addeditOrderLine.POLineProductUnitPrice = args.ItemData.ProductUnitPrice;
POLineCalc();
}
private void OnChangeTax(Syncfusion.Blazor.DropDowns.SelectEventArgs<Tax> args)
{
// int testTaxId = args.ItemData.TaxID;
this.addeditOrderLine.POLineTaxRate = args.ItemData.TaxRate;
POLineCalc();
}
private void POLineCalc()
{
addeditOrderLine.POLineNetPrice = addeditOrderLine.POLineProductUnitPrice * addeditOrderLine.POLineProductQuantity;
addeditOrderLine.POLineTaxAmount = addeditOrderLine.POLineNetPrice.Value * addeditOrderLine.POLineTaxRate;
addeditOrderLine.POLineGrossPrice = addeditOrderLine.POLineNetPrice.Value * (1 + addeditOrderLine.POLineTaxRate);
}
}
spProduct_ListBySupplier
USE [PurchaseOrders]
GO
/****** Object: StoredProcedure [dbo].[spProduct_ListBySupplier] ******/
DROP PROCEDURE [dbo].[spProduct_ListBySupplier]
GO
/****** Object: StoredProcedure [dbo].[spProduct_ListBySupplier] ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-------------- Stored Proc for SELECT (one)
CREATE PROCEDURE [dbo].[spProduct_ListBySupplier]
-- Needs one parameter for Supplier
@SupplierID int
AS
BEGIN
-- SQL Select for
SELECT ProductID,
ProductCode,
ProductDescription,
ProductUnitPrice,
ProductSupplierID,
ProductIsArchived
FROM Product
WHERE (ProductSupplierID = @SupplierID) AND (ProductIsArchived = 0) OR
(ProductSupplierID = 0) AND (ProductIsArchived = 0) OR
(ProductSupplierID IS NULL) AND (ProductIsArchived = 0)
ORDER BY ProductCode
END
GO