Files
point_of_sale_v2/PointOfSale/Pos.Ui/Pos/SalesWindow.xaml.cs

541 lines
18 KiB
C#

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Markup.Localizer;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Database.Models;
using Pos.Models;
using Pos.Service;
namespace Pos
{
/// <summary>
/// Interaction logic for SalesWindow.xaml
/// </summary>
public partial class SalesWindow : Window
{
private ObservableCollection<EmployeeEntity> _employees;
private ObservableCollection<ProductGroupEntity> _productGroups;
private ObservableCollection<SaleGridModel> _saleGridModels;
private ObservableCollection<AmountGridModel> _paymentGridModels;
private readonly SalesTransactionService _salesTransactionService =
new SalesTransactionService();
private ProductEntity _selectedProduct;
private ProductGroupEntity _selectedProductGroup;
private int _employeeId = -1;
private int _productGroupId = -1;
private int _productId = -1;
private int _selectedSaleGridIndex = -1;
private int _maxCharOfName = 0;
private Button _prevEmpButton = new Button();
private Button _prevProductGroupButton = new Button();
private Button _prevProduct = new Button();
public SalesWindow()
{
InitializeComponent();
InitialLoad();
}
private void InitialLoad()
{
CacheService.Invalidate();
_employees = CacheService.GetEmployee() as ObservableCollection<EmployeeEntity>;
_productGroups = CacheService.GetProductGroupsIncludeProducts() as ObservableCollection<ProductGroupEntity>;
_saleGridModels = new ObservableCollection<SaleGridModel>();
_paymentGridModels = new ObservableCollection<AmountGridModel>();
SaleGrid.ItemsSource = _saleGridModels;
PaymentGrid.ItemsSource = _paymentGridModels;
BuildEmployee();
BuildProductGroup();
ManipulateBuySection();
UpdateWindowTitle();
foreach (var productGroup in _productGroups)
{
if (_maxCharOfName < productGroup.Name.Length)
_maxCharOfName = productGroup.Name.Length;
foreach (ProductEntity product in productGroup.Products)
{
if (_maxCharOfName < product.Name.Length)
_maxCharOfName = product.Name.Length;
}
}
}
private void BtnPrGr_Click(object sender, RoutedEventArgs e)
{
_productId = -1;
_prevProductGroupButton.Style = (Style)FindResource("SaleButtons");
Button button = sender as Button;
_prevProductGroupButton = button;
button.Style = (Style)FindResource("SaleButtonsActive");
_productGroupId = (int)button.Tag;
_selectedProductGroup = _productGroups.Single(c => c.Id == _productGroupId);
BuildProducts(_selectedProductGroup.Products);
ManipulateBuySection();
}
private void BtnProduct_Click(object sender, RoutedEventArgs e)
{
_prevProduct.Style = (Style)FindResource("SaleButtons");
Button button = sender as Button;
_prevProduct = button;
button.Style = (Style)FindResource("SaleButtonsActive");
_productId = (int)button.Tag;
_selectedProduct = _selectedProductGroup.Products.Single(c => c.Id == _productId);
ManipulateBuySection();
}
private void BtnEmp_Click(object sender, RoutedEventArgs e)
{
_prevEmpButton.Style = (Style)FindResource("SaleButtons");
_prevProductGroupButton.Style = (Style)FindResource("SaleButtons");
//DockProduct.Children.Clear();
Button button = sender as Button;
_prevEmpButton = button;
button.Style = (Style)FindResource("SaleButtonsActive");
_employeeId = (int) button.Tag;
UIElementCollection employees = DockProductGroup.Children;
foreach (UIElement emp in employees)
{
button = (Button)emp;
button.IsEnabled = true;
}
}
private void SaleGrid_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
DataGrid dg = (DataGrid)sender;
_selectedSaleGridIndex = dg.SelectedIndex;
}
private void NumberOfProducts_GotFocus(object sender, RoutedEventArgs e)
{
NumberOfProducts.Text = string.Empty;
}
private void Buy_Click(object sender, RoutedEventArgs e)
{
bool isValid = ValidatePriceInput();
if (!isValid)
return;
isValid = ValidateNumberOfProductsInput();
if (!isValid)
return;
decimal price = Convert.ToDecimal(Price.Text);
int numberOfProducts = Convert.ToInt32(NumberOfProducts.Text);
try
{
BuildPrice(numberOfProducts, price);
}
catch (ArgumentException exception)
{
MessageBox.Show(
exception.Message,
"Ugyldig salgslinje",
MessageBoxButton.OK,
MessageBoxImage.Error);
return;
}
NumberOfProducts.Text = "1";
Price.Text = string.Empty;
TotalPrice.Content = "0";
_productId = -1;
_productGroupId = -1;
ManipulateBuySection();
}
private void Payment_Click(object sender, RoutedEventArgs e)
{
decimal? amount = null;
if (!string.IsNullOrEmpty(Amount.Text))
{
bool isValid = ValidateAmountInput();
if (!isValid)
return;
amount = Convert.ToDecimal(Amount.Text);
}
Amount.Text = string.Empty;
Button button = sender as Button;
string paymentMethodName =
((string)button.Tag).Replace("PaymentMethod.", string.Empty);
if (!Enum.TryParse(paymentMethodName, out PaymentMethod paymentMethod))
return;
try
{
BuildAmuntDataGrid(amount, paymentMethod);
}
catch (ArgumentException exception)
{
MessageBox.Show(
exception.Message,
"Ugyldig betaling",
MessageBoxButton.OK,
MessageBoxImage.Error);
}
}
private void NumberOfProducts_LostFocus(object sender, RoutedEventArgs e)
{
bool isValid = ValidateNumberOfProductsInput();
if (!isValid)
return;
CalculateSubPrice();
}
private void Price_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
Buy_Click(null,null);
}
else
{
CalculateSubPrice();
}
}
private void BuildEmployee()
{
DockProductGroup.Children.Clear();
//DockProduct.Children.Clear();
DockEmployee.Children.Clear();
bool firstEmployee = true;
foreach (EmployeeEntity employee in _employees)
{
Button btnEmp = new Button();
btnEmp.Style = (Style)FindResource("SaleButtons");
btnEmp.Content = employee.Name;
btnEmp.Tag = employee.Id;
btnEmp.Click += BtnEmp_Click;
DockEmployee.Children.Add(btnEmp);
if (firstEmployee)
{
firstEmployee = false;
btnEmp.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));
}
}
}
private void BuildProductGroup()
{
DockProductGroup.Children.Clear();
foreach (ProductGroupEntity productGroup in _productGroups)
{
Button btnPrGr = new Button();
btnPrGr.Style = (Style)FindResource("SaleButtons");
btnPrGr.Content = productGroup.Name;
btnPrGr.Tag = productGroup.Id;
btnPrGr.Click += BtnPrGr_Click;
if (_employeeId == -1)
btnPrGr.IsEnabled = false;
DockProductGroup.Children.Add(btnPrGr);
}
}
private void BuildProducts(ICollection<ProductEntity> products)
{
// DockProduct.Children.Clear();
foreach (ProductEntity product in products)
{
Button btnProduct = new Button();
btnProduct.Style = (Style)FindResource("SaleButtons");
btnProduct.Content = product.Name;
btnProduct.Tag = product.Id;
btnProduct.Click += BtnProduct_Click;
// DockProduct.Children.Add(btnProduct);
}
}
private void BuildPrice(int numberOfProducts, decimal price)
{
PriceLineModel priceLineModel;
if (_selectedProduct != null)
{
priceLineModel = _salesTransactionService.AddSaleLine(
_selectedProduct.Id,
_selectedProduct.Name,
numberOfProducts,
price,
false);
}
else
{
priceLineModel = _salesTransactionService.AddSaleLine(
_selectedProductGroup.Id,
_selectedProductGroup.Name,
numberOfProducts,
price,
true);
}
BuildPriceDataGrid(priceLineModel);
//BuildEmployee();
BuildProductGroup();
}
private void CalculateSubPrice()
{
bool isValid = decimal.TryParse(Price.Text, out decimal price);
if (!isValid)
return;
isValid = Int32.TryParse(
NumberOfProducts.Text,
out int numberOfProducts);
if (!isValid)
return;
try
{
TotalPrice.Content =
_salesTransactionService.CalculateLineTotal(
price,
numberOfProducts);
}
catch (ArgumentOutOfRangeException)
{
TotalPrice.Content = "0";
}
}
private void CalculateTotalLine()
{
Total.Content =
$"At betale: Kr. {_salesTransactionService.TotalPrice}";
}
private void BuildPriceDataGrid(PriceLineModel priceLineModel)
{
_selectedProduct = null;
_selectedProductGroup = null;
CalculateTotalLine();
SaleGridModel model = new SaleGridModel();
model.Navn = priceLineModel.Name;
model.Pris = $"kr. {priceLineModel.Price}";
model.Stk = $"- {priceLineModel.NumberProducts} stk. à";
model.Total = $"= Kr. {priceLineModel.NumberProducts * priceLineModel.Price}";
SaleGridInternalModel saleGridInternalModel = new SaleGridInternalModel();
saleGridInternalModel.InternPrice = priceLineModel.Price;
saleGridInternalModel.InternPieces = priceLineModel.NumberProducts;
model.SaleGridInternalModel = saleGridInternalModel;
//model.InternPrice = priceLineModel.Price;
//model.InternPieces = priceLineModel.NumberProducts;
_saleGridModels.Add(model);
}
private bool ValidateNumberOfProductsInput()
{
int notUsed;
bool isValid = Int32.TryParse(NumberOfProducts.Text, out notUsed);
if (!isValid)
{
MessageBox.Show($"{NumberOfProducts.Text} er ikke en gyldig værdi! \nSætter 1 som standard værdi ", "Ikke gyldig værdi",
MessageBoxButton.OK, MessageBoxImage.Error);
NumberOfProducts.Text = "1";
return false;
}
return true;
}
private bool ValidatePriceInput()
{
decimal p = 0;
bool isValid = Decimal.TryParse(Price.Text, out p);
if (!isValid)
{
string msg = "";
if (string.IsNullOrEmpty(Price.Text))
{
msg = "En tom pris er ikke en gyldig værdi!";
}
else
{
msg = $"{Price.Text} er ikke en gyldig pris!";
}
MessageBox.Show(msg, "Ugyldig pris", MessageBoxButton.OK,
MessageBoxImage.Error);
return false;
}
return true;
}
private bool ValidateAmountInput()
{
decimal p = 0;
bool isValid = Decimal.TryParse(Amount.Text, out p);
if (!isValid)
{
string msg = "";
if (string.IsNullOrEmpty(Amount.Text))
{
msg = "Et tomt beløb er ikke en gyldig værdi!";
}
else
{
msg = $"{Amount.Text} er ikke et gyldigt beløb!";
}
MessageBox.Show(msg, "Ugyldigt beløb", MessageBoxButton.OK,
MessageBoxImage.Error);
return false;
}
return true;
}
private void ManipulateBuySection()
{
bool enabled = _productGroupId > 0 || _productId > 0;
PricePanel.IsEnabled = enabled;
NumberOfProducts.IsEnabled = enabled;
Price.IsEnabled = enabled;
Price.Focus();
BtnBuy.IsEnabled = enabled;
LblStk.IsEnabled = enabled;
LblPrice.IsEnabled = enabled;
LblTotal.IsEnabled = enabled;
TotalPrice.IsEnabled = enabled;
}
private void BuildAmuntDataGrid(
decimal? amount,
PaymentMethod paymentMethod)
{
AmountGridModel amountGridModel =
_salesTransactionService.AddPayment(paymentMethod, amount);
amountGridModel.AmountText = $"Kr. {amountGridModel.Amount}";
_paymentGridModels.Add(amountGridModel);
AmountPayed();
}
private void AmountPayed()
{
if (_salesTransactionService.AmountPaid ==
_salesTransactionService.TotalPrice)
{
btnFinish_Click(null,null);
return;
}
if (_salesTransactionService.Change > 0)
{
lblRecived.Content =
$"Byttepenge: Kr. {_salesTransactionService.Change}";
Style style = this.FindResource("BoldLabelWarningNoMargin") as Style;
lblRecived.Style = style;
btnFinish.IsEnabled = true;
}
else
{
lblRecived.Content =
$"At betale: Kr. {_salesTransactionService.RemainingAmount}";
Style style = this.FindResource("BoldLabelNoMargin") as Style;
lblRecived.Style = style;
}
}
private void SaleGrid_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Delete)
{
if (_selectedSaleGridIndex == -1)
return;
int index = _selectedSaleGridIndex;
_salesTransactionService.RemoveSaleLineAt(index);
_saleGridModels.RemoveAt(index);
_selectedSaleGridIndex = -1;
CalculateTotalLine();
if (_salesTransactionService.AmountPaid > 0)
AmountPayed();
}
}
private void btnFinish_Click(object sender, RoutedEventArgs e)
{
try
{
_salesTransactionService.EnsureCanComplete();
}
catch (InvalidOperationException exception)
{
MessageBox.Show(
exception.Message,
"Salget kan ikke afsluttes",
MessageBoxButton.OK,
MessageBoxImage.Error);
return;
}
SaleService saleService = new SaleService();
saleService.Save(_saleGridModels.ToList(),_paymentGridModels.ToList(),_employeeId);
_paymentGridModels.Clear();
_salesTransactionService.Reset();
UpdateWindowTitle();
_saleGridModels.Clear();
lblRecived.Content = string.Empty;
_selectedSaleGridIndex = -1;
btnFinish.IsEnabled = false;
CalculateTotalLine();
BuildEmployee();
BuildProductGroup();
ManipulateBuySection();
}
private void BtnPrint_Click(object sender, RoutedEventArgs e)
{
SaleService saleService = new SaleService();
saleService.PrintReceipt();
}
private void UpdateWindowTitle()
{
SaleService saleService = new SaleService();
Title = saleService.LastAndTotalSale();
}
}
}