diff --git a/RMData/RMData.sqlproj b/RMData/RMData.sqlproj
index a8988d0..d5d7e5b 100644
--- a/RMData/RMData.sqlproj
+++ b/RMData/RMData.sqlproj
@@ -73,6 +73,10 @@
+
+
+
+
diff --git a/RMData/dbo/Stored Procedures/spProductGetById.sql b/RMData/dbo/Stored Procedures/spProductGetById.sql
new file mode 100644
index 0000000..7e5248e
--- /dev/null
+++ b/RMData/dbo/Stored Procedures/spProductGetById.sql
@@ -0,0 +1,10 @@
+CREATE PROCEDURE [dbo].[spProductGetById]
+ @Id int
+AS
+BEGIN
+ SET NOCOUNT ON;
+
+ select Id, ProductName, [Description], RetailPrice, QuantityInStock, IsTaxable
+ from [dbo].[Product]
+ where Id = @Id;
+END
diff --git a/RMData/dbo/Stored Procedures/spSaleDetailInsert.sql b/RMData/dbo/Stored Procedures/spSaleDetailInsert.sql
new file mode 100644
index 0000000..bb502e8
--- /dev/null
+++ b/RMData/dbo/Stored Procedures/spSaleDetailInsert.sql
@@ -0,0 +1,14 @@
+CREATE PROCEDURE [dbo].[spSaleDetailInsert]
+ @SaleId int,
+ @ProductId int,
+ @Quantity int,
+ @PurchasePrice money,
+ @Tax money
+AS
+BEGIN
+ SET NOCOUNT ON;
+
+ INSERT INTO dbo.SaleDetail(SaleId, ProductId, Quantity, PurchasePrice, Tax)
+ VALUES (@SaleId, @ProductId, @Quantity, @PurchasePrice, @Tax)
+
+END
\ No newline at end of file
diff --git a/RMData/dbo/Stored Procedures/spSaleInsert.sql b/RMData/dbo/Stored Procedures/spSaleInsert.sql
new file mode 100644
index 0000000..2a2a40d
--- /dev/null
+++ b/RMData/dbo/Stored Procedures/spSaleInsert.sql
@@ -0,0 +1,16 @@
+CREATE PROCEDURE [dbo].[spSaleInsert]
+ @Id int output,
+ @CashierId nvarchar(128),
+ @SaleDate datetime2,
+ @SubTotal money,
+ @Tax money,
+ @Total money
+AS
+BEGIN
+ SET NOCOUNT ON;
+
+ INSERT INTO dbo.Sale(CashierId, SaleDate, SubTotal, Tax, Total)
+ VALUES (@CashierId, @SaleDate, @SubTotal, @Tax, @Total);
+
+ SELECT @Id = @@IDENTITY;
+END
\ No newline at end of file
diff --git a/RMData/dbo/Stored Procedures/spSaleLookUp.sql b/RMData/dbo/Stored Procedures/spSaleLookUp.sql
new file mode 100644
index 0000000..4cdee49
--- /dev/null
+++ b/RMData/dbo/Stored Procedures/spSaleLookUp.sql
@@ -0,0 +1,11 @@
+CREATE PROCEDURE [dbo].[spSaleLookUp]
+ @CashierId nvarchar(128),
+ @SaleDate datetime2
+AS
+BEGIN
+ SET NOCOUNT ON;
+
+ Select Id
+ from dbo.Sale
+ where CashierId = @CashierId and SaleDate = @SaleDate;
+END
diff --git a/RMDataManager/Controllers/SaleController.cs b/RMDataManager/Controllers/SaleController.cs
new file mode 100644
index 0000000..cd445db
--- /dev/null
+++ b/RMDataManager/Controllers/SaleController.cs
@@ -0,0 +1,24 @@
+using Microsoft.AspNet.Identity;
+using RMDataManagerLibrary.DataAcccess;
+using RMDataManagerLibrary.Models;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Web.Http;
+
+namespace RMDataManager.Controllers
+{
+ [Authorize]
+ public class SaleController : ApiController
+ {
+ public void Post(SaleModel sale)
+ {
+ string cashierId = RequestContext.Principal.Identity.GetUserId();
+ SaleData data = new SaleData();
+
+ data.SaveSale(sale, cashierId);
+ }
+ }
+}
diff --git a/RMDataManager/RMDataManager.csproj b/RMDataManager/RMDataManager.csproj
index ca6a8ed..4f9dd0f 100644
--- a/RMDataManager/RMDataManager.csproj
+++ b/RMDataManager/RMDataManager.csproj
@@ -214,6 +214,7 @@
+
diff --git a/RMDataManager/Web.config b/RMDataManager/Web.config
index 120ea28..210a360 100644
--- a/RMDataManager/Web.config
+++ b/RMDataManager/Web.config
@@ -13,6 +13,7 @@
+
diff --git a/RMDataManagerLibrary/ConfigHelper.cs b/RMDataManagerLibrary/ConfigHelper.cs
new file mode 100644
index 0000000..4d8bba2
--- /dev/null
+++ b/RMDataManagerLibrary/ConfigHelper.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace RMDataManagerLibrary
+{
+ public class ConfigHelper
+ {
+ public static decimal GetTaxRate()
+ {
+ string rateText = ConfigurationManager.AppSettings["taxRate"];
+
+ bool isValidTaxRate = Decimal.TryParse(rateText, out decimal output);
+
+ if (isValidTaxRate == false)
+ {
+ throw new ConfigurationErrorsException("The taxRate is not setup properly");
+ }
+
+ return output;
+ }
+ }
+}
diff --git a/RMDataManagerLibrary/DataAcccess/ProductData.cs b/RMDataManagerLibrary/DataAcccess/ProductData.cs
index db78ae4..a1b1cf6 100644
--- a/RMDataManagerLibrary/DataAcccess/ProductData.cs
+++ b/RMDataManagerLibrary/DataAcccess/ProductData.cs
@@ -18,5 +18,14 @@ namespace RMDataManagerLibrary.DataAcccess
return output;
}
+
+ public ProductModel GetProductById(int productId)
+ {
+ SqlDataAccess sql = new SqlDataAccess();
+
+ var output = sql.LoadData("dbo.spProductGetById", new {Id = productId}, "RMData").FirstOrDefault();
+
+ return output;
+ }
}
}
diff --git a/RMDataManagerLibrary/DataAcccess/SaleData.cs b/RMDataManagerLibrary/DataAcccess/SaleData.cs
new file mode 100644
index 0000000..10c195b
--- /dev/null
+++ b/RMDataManagerLibrary/DataAcccess/SaleData.cs
@@ -0,0 +1,76 @@
+using RMDataManagerLibrary.Internal.DataAccess;
+using RMDataManagerLibrary.Models;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace RMDataManagerLibrary.DataAcccess
+{
+ public class SaleData
+ {
+ //TODO: Make this SOLID/DRY/BETTER
+ public void SaveSale(SaleModel saleInfo, string cashierId)
+ {
+ List details = new List();
+ ProductData products = new ProductData();
+ decimal taxRate = ConfigHelper.GetTaxRate()/100;
+
+ foreach (var item in saleInfo.SaleDetails)
+ {
+ var detail = new SaleDetailDBModel
+ {
+ ProductId = item.ProductId,
+ Quantity = item.Quantity
+ };
+
+ // get the information about this product
+ var productInfo = products.GetProductById(item.ProductId);
+
+ if (productInfo == null)
+ {
+ throw new Exception($"Product with Id {item.ProductId} could not be found in DB");
+ }
+
+ detail.PurchasePrice = productInfo.RetailPrice * detail.Quantity;
+
+ if (productInfo.IsTaxable)
+ {
+ detail.Tax = detail.PurchasePrice * taxRate;
+ }
+
+ details.Add(detail);
+ }
+
+ SaleDBModel sale = new SaleDBModel
+ {
+ SubTotal = details.Sum(x => x.PurchasePrice),
+ Tax = details.Sum(x => x.Tax),
+ CashierId = cashierId
+ };
+
+ sale.Total = sale.SubTotal + sale.Tax;
+
+ //save
+ SqlDataAccess sql = new SqlDataAccess();
+ sql.SaveData("dbo.spSaleInsert", sale, "RMData");
+
+ // get id from saleModel
+
+ sale.Id = sql.LoadData("spSaleLookUp",new { sale.CashierId, sale.SaleDate }, "RMData").FirstOrDefault();
+
+ // finish filling up sale details
+ foreach (var item in details)
+ {
+ item.SaleId = sale.Id;
+
+ // Save Details
+
+ sql.SaveData("dbo.spSaleDetailInsert", item, "RMData");
+ }
+
+
+ }
+ }
+}
diff --git a/RMDataManagerLibrary/Models/SaleDBModel.cs b/RMDataManagerLibrary/Models/SaleDBModel.cs
new file mode 100644
index 0000000..1e40a09
--- /dev/null
+++ b/RMDataManagerLibrary/Models/SaleDBModel.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace RMDataManagerLibrary.Models
+{
+ public class SaleDBModel
+ {
+ public int Id { get; set; }
+ public string CashierId { get; set; }
+ public DateTime SaleDate { get; set; } = DateTime.UtcNow;
+ public decimal SubTotal { get; set; }
+ public decimal Tax { get; set; }
+ public decimal Total { get; set; }
+
+
+ }
+}
diff --git a/RMDataManagerLibrary/Models/SaleDetailDBModel.cs b/RMDataManagerLibrary/Models/SaleDetailDBModel.cs
new file mode 100644
index 0000000..07f14b5
--- /dev/null
+++ b/RMDataManagerLibrary/Models/SaleDetailDBModel.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace RMDataManagerLibrary.Models
+{
+ public class SaleDetailDBModel
+ {
+ public int SaleId { get; set; }
+ public int ProductId { get; set; }
+ public int Quantity { get; set; }
+ public decimal PurchasePrice { get; set; }
+ public decimal Tax { get; set; }
+ }
+}
diff --git a/RMDataManagerLibrary/Models/SaleDetailModel.cs b/RMDataManagerLibrary/Models/SaleDetailModel.cs
new file mode 100644
index 0000000..d26f2d0
--- /dev/null
+++ b/RMDataManagerLibrary/Models/SaleDetailModel.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+
+namespace RMDataManagerLibrary.Models
+{
+ public class SaleDetailModel
+ {
+ public int ProductId { get; set; }
+ public int Quantity { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/RMDataManagerLibrary/Models/SaleModel.cs b/RMDataManagerLibrary/Models/SaleModel.cs
new file mode 100644
index 0000000..ac68bca
--- /dev/null
+++ b/RMDataManagerLibrary/Models/SaleModel.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+
+namespace RMDataManagerLibrary.Models
+{
+ public class SaleModel
+ {
+ public List SaleDetails { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/RMDataManagerLibrary/RMDataManagerLibrary.csproj b/RMDataManagerLibrary/RMDataManagerLibrary.csproj
index 5ee02f4..1ff33d7 100644
--- a/RMDataManagerLibrary/RMDataManagerLibrary.csproj
+++ b/RMDataManagerLibrary/RMDataManagerLibrary.csproj
@@ -45,9 +45,15 @@
+
+
+
+
+
+
diff --git a/RMWPFInterfaceLibrary/Api/ISaleEndPoint.cs b/RMWPFInterfaceLibrary/Api/ISaleEndPoint.cs
new file mode 100644
index 0000000..b9d9028
--- /dev/null
+++ b/RMWPFInterfaceLibrary/Api/ISaleEndPoint.cs
@@ -0,0 +1,10 @@
+using RMWPFInterfaceLibrary.Models;
+using System.Threading.Tasks;
+
+namespace RMWPFInterfaceLibrary.Api
+{
+ public interface ISaleEndPoint
+ {
+ Task PostSale(SaleModel sale);
+ }
+}
\ No newline at end of file
diff --git a/RMWPFInterfaceLibrary/Api/SaleEndPoint.cs b/RMWPFInterfaceLibrary/Api/SaleEndPoint.cs
new file mode 100644
index 0000000..3c3a010
--- /dev/null
+++ b/RMWPFInterfaceLibrary/Api/SaleEndPoint.cs
@@ -0,0 +1,34 @@
+using RMWPFInterfaceLibrary.Models;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace RMWPFInterfaceLibrary.Api
+{
+ public class SaleEndPoint : ISaleEndPoint
+ {
+ private IAPIHelper _apiHelper;
+ public SaleEndPoint(IAPIHelper apiHelper)
+ {
+ _apiHelper = apiHelper;
+ }
+
+ public async Task PostSale(SaleModel sale)
+ {
+ using (HttpResponseMessage response = await _apiHelper.ApiClient.PostAsJsonAsync("api/Sale", sale))
+ {
+ if (response.IsSuccessStatusCode)
+ {
+ // Log call
+ }
+ else
+ {
+ throw new Exception(response.ReasonPhrase);
+ }
+ }
+ }
+ }
+}
diff --git a/RMWPFInterfaceLibrary/Models/SaleDetailModel.cs b/RMWPFInterfaceLibrary/Models/SaleDetailModel.cs
new file mode 100644
index 0000000..1d4d0d4
--- /dev/null
+++ b/RMWPFInterfaceLibrary/Models/SaleDetailModel.cs
@@ -0,0 +1,8 @@
+namespace RMWPFInterfaceLibrary.Models
+{
+ public class SaleDetailModel
+ {
+ public int ProductId { get; set; }
+ public int Quantity { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/RMWPFInterfaceLibrary/Models/SaleModel.cs b/RMWPFInterfaceLibrary/Models/SaleModel.cs
new file mode 100644
index 0000000..9807f07
--- /dev/null
+++ b/RMWPFInterfaceLibrary/Models/SaleModel.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace RMWPFInterfaceLibrary.Models
+{
+ public class SaleModel
+ {
+ public List SaleDetails { get; set; } = new List();
+ }
+}
diff --git a/RMWPFInterfaceLibrary/RMWPFInterfaceLibrary.csproj b/RMWPFInterfaceLibrary/RMWPFInterfaceLibrary.csproj
index 3be943e..fc9c8d3 100644
--- a/RMWPFInterfaceLibrary/RMWPFInterfaceLibrary.csproj
+++ b/RMWPFInterfaceLibrary/RMWPFInterfaceLibrary.csproj
@@ -51,7 +51,9 @@
+
+
@@ -59,6 +61,8 @@
+
+
diff --git a/RMWPFUserInterface/BootStrapper.cs b/RMWPFUserInterface/BootStrapper.cs
index c568307..a4072b3 100644
--- a/RMWPFUserInterface/BootStrapper.cs
+++ b/RMWPFUserInterface/BootStrapper.cs
@@ -29,7 +29,8 @@ namespace RMWPFUserInterface
protected override void Configure()
{
_container.Instance(_container)
- .PerRequest();
+ .PerRequest()
+ .PerRequest();
_container
.Singleton()
diff --git a/RMWPFUserInterface/ViewModels/LoginViewModel.cs b/RMWPFUserInterface/ViewModels/LoginViewModel.cs
index 58b6e16..1a87fb1 100644
--- a/RMWPFUserInterface/ViewModels/LoginViewModel.cs
+++ b/RMWPFUserInterface/ViewModels/LoginViewModel.cs
@@ -12,8 +12,8 @@ namespace RMWPFUserInterface.ViewModels
{
public class LoginViewModel : Screen
{
- private string _userName;
- private string _password;
+ private string _userName ="test@test";
+ private string _password = "Test1234.";
private IAPIHelper _apiHelper;
private IEventAggregator _events;
diff --git a/RMWPFUserInterface/ViewModels/SalesViewModel.cs b/RMWPFUserInterface/ViewModels/SalesViewModel.cs
index b0bc128..fbcd142 100644
--- a/RMWPFUserInterface/ViewModels/SalesViewModel.cs
+++ b/RMWPFUserInterface/ViewModels/SalesViewModel.cs
@@ -15,10 +15,13 @@ namespace RMWPFUserInterface.ViewModels
{
IProductEndPoint _productEndPoint;
IConfigHelper _configHelper;
- public SalesViewModel(IProductEndPoint productEndPoint, IConfigHelper configHelper)
+ ISaleEndPoint _saleEndPoint;
+
+ public SalesViewModel(IProductEndPoint productEndPoint, IConfigHelper configHelper, ISaleEndPoint saleEndPoint)
{
_productEndPoint = productEndPoint;
_configHelper = configHelper;
+ _saleEndPoint = saleEndPoint;
}
protected override async void OnViewLoaded(object view)
@@ -170,6 +173,7 @@ namespace RMWPFUserInterface.ViewModels
NotifyOfPropertyChange(() => SubTotal);
NotifyOfPropertyChange(() => Tax);
NotifyOfPropertyChange(() => Total);
+ NotifyOfPropertyChange(() => CanCheckOut);
Cart.ResetBindings();
}
@@ -189,6 +193,7 @@ namespace RMWPFUserInterface.ViewModels
NotifyOfPropertyChange(() => SubTotal);
NotifyOfPropertyChange(() => Tax);
NotifyOfPropertyChange(() => Total);
+ NotifyOfPropertyChange(() => CanCheckOut);
}
public bool CanCheckOut
@@ -197,14 +202,29 @@ namespace RMWPFUserInterface.ViewModels
{
bool output = false;
- // Make sure there is something in the cart
+ if ( Cart.Count > 0)
+ {
+ output = true;
+ }
return output;
}
}
- public void CheckOut()
+ public async Task CheckOut()
{
+ SaleModel sale = new SaleModel();
+ foreach (var item in Cart)
+ {
+ sale.SaleDetails.Add(new SaleDetailModel
+ {
+ ProductId = item.Product.Id,
+ Quantity = item.QuantityInCart
+ });
+
+ }
+
+ await _saleEndPoint.PostSale(sale);
}
}
}
diff --git a/RMWPFUserInterface/Views/SalesView.xaml b/RMWPFUserInterface/Views/SalesView.xaml
index c9f499f..83ef5ed 100644
--- a/RMWPFUserInterface/Views/SalesView.xaml
+++ b/RMWPFUserInterface/Views/SalesView.xaml
@@ -43,7 +43,7 @@
-
+