using AutoMapper; using Caliburn.Micro; using RMWPFInterfaceLibrary.Api; using RMWPFInterfaceLibrary.Helpers; using RMWPFInterfaceLibrary.Models; using RMWPFUserInterface.Models; using System; using System.Collections.Generic; using System.ComponentModel; using System.Dynamic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; namespace RMWPFUserInterface.ViewModels { public class SalesViewModel : Screen { IProductEndPoint _productEndPoint; IConfigHelper _configHelper; ISaleEndPoint _saleEndPoint; IMapper _mapper; private readonly StatusInfoViewModel _status; private readonly IWindowManager _window; public SalesViewModel(IProductEndPoint productEndPoint, IConfigHelper configHelper, ISaleEndPoint saleEndPoint, IMapper mapper, StatusInfoViewModel status, IWindowManager window) { _productEndPoint = productEndPoint; _configHelper = configHelper; _saleEndPoint = saleEndPoint; _mapper = mapper; _status = status; _window = window; } protected override async void OnViewLoaded(object view) { base.OnViewLoaded(view); try { await LoadProducts(); } catch (Exception ex) { dynamic settings = new ExpandoObject(); settings.WindowStartUpLocation = WindowStartupLocation.CenterOwner; settings.ResizeMode = ResizeMode.NoResize; settings.Title = "System Error"; if (ex.Message == "Unauthorized") { _status.UpdateMessage("Unauthorized Access", "You do not have permission to interact with Sales Form."); _window.ShowDialogAsync(_status, null, settings); } else { _status.UpdateMessage("Fatal exception", ex.Message); _window.ShowDialogAsync(_status, null, settings); } TryCloseAsync(); } } private async Task LoadProducts() { var products_lsit = await _productEndPoint.GetAll(); var products = _mapper.Map>(products_lsit); Products = new BindingList(products); } private async Task ResetSalesViewModel() { Cart = new BindingList(); // TODO - Add clearing selectedCartItem if that does not clear it await LoadProducts(); NotifyOfPropertyChange(() => SubTotal); NotifyOfPropertyChange(() => Tax); NotifyOfPropertyChange(() => Total); NotifyOfPropertyChange(() => CanCheckOut); NotifyOfPropertyChange(() => CanAddToCart); } private BindingList _products; public BindingList Products { get { return _products; } set { _products = value; NotifyOfPropertyChange(() => Products); } } private ProductDisplayModel _selectedProduct; public ProductDisplayModel SelectedProduct { get { return _selectedProduct; } set { _selectedProduct = value; NotifyOfPropertyChange(() => SelectedProduct); NotifyOfPropertyChange(() => CanAddToCart); } } private CartItemDisplayModel _selectedCartItem; public CartItemDisplayModel SelectedCartItem { get { return _selectedCartItem; } set { _selectedCartItem = value; NotifyOfPropertyChange(() => SelectedCartItem); NotifyOfPropertyChange(() => CanRemoveFromCart); } } private BindingList _cart = new BindingList(); public BindingList Cart { get { return _cart; } set { _cart = value; NotifyOfPropertyChange(() => Cart); } } private int _itemQuantity = 1; public int ItemQuantity { get { return _itemQuantity; } set { _itemQuantity = value; NotifyOfPropertyChange(() => ItemQuantity); NotifyOfPropertyChange(() => CanAddToCart); } } public string SubTotal { get { return CalculateSubTotal().ToString("C"); } } private decimal CalculateSubTotal() { decimal subTotal = 0; foreach (var item in Cart) { subTotal += item.Product.RetailPrice * item.QuantityInCart; } return subTotal; } public string Tax { get { return CalculateTax().ToString("C"); } } private decimal CalculateTax() { decimal taxAmount = 0; decimal TaxRate = _configHelper.GetTaxRate()/100; taxAmount = Cart .Where(x => x.Product.IsTaxable) .Sum(x => x.Product.RetailPrice * x.QuantityInCart * TaxRate); return taxAmount; } public string Total { get { decimal total = CalculateSubTotal() + CalculateTax(); return total.ToString("C"); } } public bool CanAddToCart { get { bool output = false; if (ItemQuantity > 0 && SelectedProduct?.QuantityInStock >= ItemQuantity) { output = true; } return output; } } public void AddToCart() { CartItemDisplayModel existingItem = Cart.FirstOrDefault(x => x.Product == SelectedProduct); if (existingItem != null) { existingItem.QuantityInCart += ItemQuantity; } else { CartItemDisplayModel item = new CartItemDisplayModel { Product = SelectedProduct, QuantityInCart = ItemQuantity }; Cart.Add(item); } SelectedProduct.QuantityInStock -= ItemQuantity; ItemQuantity = 1; NotifyOfPropertyChange(() => SubTotal); NotifyOfPropertyChange(() => Tax); NotifyOfPropertyChange(() => Total); NotifyOfPropertyChange(() => CanCheckOut); } public bool CanRemoveFromCart { get { bool output = false; // Make sure something is selected if (SelectedCartItem != null && SelectedCartItem?.QuantityInCart > 0) { output = true; } return output; } } public void RemoveFromCart() { SelectedCartItem.Product.QuantityInStock += 1; if (SelectedCartItem.QuantityInCart > 1) { SelectedCartItem.QuantityInCart -= 1; } else { Cart.Remove(SelectedCartItem); } NotifyOfPropertyChange(() => SubTotal); NotifyOfPropertyChange(() => Tax); NotifyOfPropertyChange(() => Total); NotifyOfPropertyChange(() => CanCheckOut); NotifyOfPropertyChange(() => CanAddToCart); } public bool CanCheckOut { get { bool output = false; if ( Cart.Count > 0) { output = true; } return output; } } 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); await ResetSalesViewModel(); } } }