Major refactor of the Sales Form and Bill controller to make code more readable and less error prone.

The functions now only do one thing.
This commit is contained in:
tanshu
2016-03-31 12:27:39 +05:30
parent bb2db24837
commit 51d518d2a0
17 changed files with 615 additions and 396 deletions

View File

@ -13,8 +13,8 @@ namespace Tanshu.Accounts.PointOfSale
{
public class BillController
{
private readonly BillDict _bill;
private Voucher _voucher;
public readonly BillDict _bill;
public Voucher _voucher;
private Guid? _editVoucherID;
private ISaleForm _saleForm;
@ -22,45 +22,13 @@ namespace Tanshu.Accounts.PointOfSale
{
this._editVoucherID = editVoucherID;
_bill = new BillDict();
_voucher = new Voucher(Session.User);
using (var bi = new CustomerBI())
_voucher.Customer = bi.Get(x => x.CustomerID == Constants.CASH_CUSTOMER);
}
public BillItemValue CurrentProduct
{
get
{
if (_saleForm.BindingSource.Position == -1)
return null;
var item = _bill.ElementAt(_saleForm.BindingSource.Position);
return item.Key.BillItemType != BillItemType.Kot ? item.Value : null;
}
}
public BillItemKey CurrentKey
{
get
{
if (_saleForm.BindingSource.Position == -1)
return null;
var item = _bill.ElementAt(_saleForm.BindingSource.Position);
return item.Key;
}
}
public BillItemKey CurrentKot
{
get
{
if (_saleForm.BindingSource.Position == -1)
return null;
var item = _bill.ElementAt(_saleForm.BindingSource.Position);
return item.Key.BillItemType == BillItemType.Kot ? item.Key : null;
}
_voucher = new Voucher(Session.User, bi.Get(x => x.CustomerID == Constants.CASH_CUSTOMER));
}
public void InitGui(ISaleForm saleForm)
{
this._saleForm = saleForm;
this._saleForm.SetCustomerDisplay(_voucher.Customer.Name);
this._saleForm.SetUserName(Session.User.Name);
}
public void AddProduct(Product product)
@ -69,7 +37,6 @@ namespace Tanshu.Accounts.PointOfSale
if (_bill.ContainsKey(newKey))
{
_saleForm.BindingSource.CurrencyManager.Position = _bill.IndexOfKey(newKey);
_bill[newKey].inventory.Quantity += 1;
}
else
@ -82,32 +49,20 @@ namespace Tanshu.Accounts.PointOfSale
billItemValue.inventory.Price = old.Value.inventory.Price;
}
_bill.Add(newKey, billItemValue);
_saleForm.BindingSource.DataSource = _bill.ToList();
_saleForm.BindingSource.CurrencyManager.Position = _saleForm.BindingSource.CurrencyManager.Count - 1;
using (var bi = new ProductGroupModifierBI())
if (bi.HasCompulsoryModifier(product.ProductGroup.ProductGroupID))
{
ShowModifiers();
}
}
ShowAmount();
}
public void ShowModifiers()
public void ShowModifiers(BillItemValue item)
{
var item = CurrentProduct;
if (item == null || CurrentKey.KotID != Guid.Empty)
return; // No Product or Old Product
using (var frm = new ModifierForm(Cache.ProductGroupModifiers(item.inventory.Product.ProductGroup.ProductGroupID), item.inventory.InventoryModifier))
{
frm.ShowDialog();
}
ShowAmount();
}
public void SetDiscount()
{
if (!Session.IsAllowed("Discount"))
return; // throw new PermissionException("Not Allowed to give Discount");
return;
using (var bi = new ProductGroupBI())
{
@ -119,7 +74,7 @@ namespace Tanshu.Accounts.PointOfSale
var discount = frm.Selection(out outList);
discount = discount / 100;
if (discount > 1 || discount < 0)
return; // throw new ValidationException("Invalid Discount Amount");
return;
foreach (var item in _bill.Where(x => x.Key.BillItemType == BillItemType.Product && outList.Contains(x.Value.inventory.Product.ProductGroup.GroupType)))
{
@ -133,12 +88,9 @@ namespace Tanshu.Accounts.PointOfSale
}
}
}
ShowAmount();
}
public void SetQuantity(decimal quantity, bool prompt)
public void SetQuantity(BillItemKey key, BillItemValue item, decimal quantity, bool prompt)
{
var item = CurrentProduct;
var key = CurrentKey;
if (item == null || key.KotID != Guid.Empty)
return; // No Product or Old Product
if (prompt && !GetInput("Quantity", ref quantity))
@ -147,21 +99,14 @@ namespace Tanshu.Accounts.PointOfSale
quantity += item.inventory.Quantity;
if (quantity < 0 && !Session.IsAllowed("Edit Printed Product"))
return;
//TODO: check if he kotid of the item is not null
//var total = quantity + _bill.Where(x => x.Key.ProductID == item.ProductID && x.Key.BillItemType == BillItemType.Product && x.Value.Printed).Sum(x => x.Value.Quantity);
var total = quantity + _bill.Where(x => x.Key.ProductID == key.ProductID && x.Key.BillItemType == key.BillItemType).Sum(x => x.Value.inventory.Quantity);
if (total < 0)
quantity -= total;
var total = quantity + _bill.Where(x => x.Key.ProductID == key.ProductID && x.Key.KotID != Guid.Empty && x.Key.BillItemType == key.BillItemType).Sum(x => x.Value.inventory.Quantity);
quantity = Math.Max(quantity, 0);
item.inventory.Quantity = quantity;
ShowAmount();
}
public void SetPrice()
public void SetPrice(BillItemValue item)
{
var item = CurrentProduct;
if (item == null)
throw new ValidationException("No Product Selected");
if (!Session.IsAllowed("Change Rate"))
throw new PermissionException("Price Change not Allowed");
return;
var price = item.inventory.Price;
if (!GetInput("Price", ref price))
return;
@ -169,46 +114,14 @@ namespace Tanshu.Accounts.PointOfSale
throw new PermissionException("NC of Product is not Allowed");
foreach (var sub in _bill.Where(x => x.Key.BillItemType == BillItemType.Product && x.Key.ProductID == item.inventory.Product.ProductID))
sub.Value.inventory.Price = price;
ShowAmount();
}
public void ShowCustomers(bool reset)
public void ShowCustomers()
{
if (!reset && ((_voucher.Customer == null) || _voucher.Customer.CustomerID == Constants.CASH_CUSTOMER))
using (var frm = new CustomerListForm())
{
using (var selectCustomer = new SelectCustomer(CustomerBI.StaticList, true))
{
selectCustomer.CustomerEvent += selectCustomer_customerEvent;
selectCustomer.ShowDialog();
if (selectCustomer.SelectedItem != null)
{
_voucher.Customer = selectCustomer.SelectedItem;
}
else
{
using (var bi = new CustomerBI())
_voucher.Customer = bi.Get(x => x.CustomerID == Constants.CASH_CUSTOMER);
}
}
frm.ShowDialog();
_voucher.Customer = frm.SelectedItem;
}
else
{
using (var bi = new CustomerBI())
_voucher.Customer = bi.Get(x => x.CustomerID == Constants.CASH_CUSTOMER);
}
_saleForm.SetCustomerDisplay(_voucher.Customer.Name);
}
private Customer selectCustomer_customerEvent(object sender, CustomerEventArgs e)
{
using (var form = new CustomersForm(e.CustomerID, e.Phone))
{
form.ShowDialog();
return form.Customer;
}
}
private void ShowAmount()
{
_saleForm.ShowAmount(_bill.Discount, _bill.NetAmount, _bill.ServiceCharge, _bill.Tax, _bill.Amount, _bill);
}
private static bool IsPrintedOrVoid(Voucher voucher)
{
@ -236,13 +149,10 @@ namespace Tanshu.Accounts.PointOfSale
{
_voucher = bi.Get(x => x.VoucherID == voucherID);
_bill.Clear();
_saleForm.ShowInfo(_voucher);
_bill.Load(_voucher);
var newKotKey = new BillItemKey(Guid.Empty);
var newKotItem = new BillItemValue();
_bill.Add(newKotKey, newKotItem);
ShowAmount();
_saleForm.FormState = SaleFormState.Billing;
}
}
public void LoadBill(string tableName)
@ -261,37 +171,37 @@ namespace Tanshu.Accounts.PointOfSale
frm.ShowDialog();
_voucher.Table = table;
_voucher.Pax = frm.Pax;
_saleForm.ShowInfo(_voucher);
}
}
}
public void CancelBillChanges()
public bool CancelBillChanges()
{
if (_bill.Any(x => x.Key.BillItemType != BillItemType.Kot) &&
MessageBox.Show("Abandon Changes?", "Abandon Changes", MessageBoxButtons.YesNo,
MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.No)
return;
return false;
ClearBill();
return true;
}
public void ClearBill()
{
_voucher = new Voucher(Session.User);
ShowCustomers(true);
using (var bi = new CustomerBI())
_voucher = new Voucher(Session.User, bi.Get(x => x.CustomerID == Constants.CASH_CUSTOMER));
_bill.Clear();
var newKotKey = new BillItemKey(Guid.Empty);
var newKotItem = new BillItemValue();
_bill.Add(newKotKey, newKotItem);
_saleForm.ClearBill(_bill);
}
public SaleFormState FormLoad()
{
ClearBill();
if (_editVoucherID.HasValue)
{
FoodTable ft = new FoodTableBI().Get(x => x.VoucherID == _editVoucherID.Value);
if (ft == null)
{
LoadBill(_editVoucherID.Value);
}
else
{
_editVoucherID = null;
@ -301,10 +211,10 @@ namespace Tanshu.Accounts.PointOfSale
}
return SaleFormState.Waiting;
}
internal void SettleBill()
internal bool SettleBill()
{
if (_voucher.VoucherID == Guid.Empty || !_voucher.Printed || !Session.IsAllowed("Settle Bill"))
return;
return false;
IDictionary<SettleOption, decimal> options;
var amount = -1 * _voucher.Kots.Sum(x => x.Inventories.Sum(y => y.Amount));
using (var frm = new SettleChoicesForm(Math.Round(amount) * -1, _voucher.VoucherType))
@ -313,7 +223,7 @@ namespace Tanshu.Accounts.PointOfSale
options = frm.OptionsChosen;
}
if (options.Count == 0)
return;
return false;
using (var bi = new VoucherBI())
{
bi.SettleVoucher(Session.User, _voucher.VoucherID, options);
@ -322,6 +232,7 @@ namespace Tanshu.Accounts.PointOfSale
bi.SaveChanges();
}
ClearBill();
return true;
}
#region Move Table(s) / Kot(s)
@ -338,11 +249,11 @@ namespace Tanshu.Accounts.PointOfSale
return null;
}
}
internal void MoveKot()
internal void MoveKot(BillItemKey currentKot)
{
if (_voucher.VoucherID == Guid.Empty || IsPrintedOrVoid(_voucher))
return;
var kot = CurrentKot;
var kot = currentKot;
if (kot == null)
return;
var table = GetTableForMove(true);
@ -368,7 +279,9 @@ namespace Tanshu.Accounts.PointOfSale
//Merge Table
voucherID = MergeTable(table);
if (voucherID != Guid.Empty)
{
LoadBill(voucherID);
}
}
internal void MoveTable()
{
@ -439,15 +352,31 @@ namespace Tanshu.Accounts.PointOfSale
#endregion
#region Save
public void SaveKot()
public bool SaveAndPrintKot()
{
#region Check if Allowed
if (!Session.IsAllowed("Print Kot"))
return;
if (!Session.IsAllowed("Print Kot") || _bill.Count(x => x.Key.BillItemType == BillItemType.Product) == 0)
return false;
bool isPrinted = false, isVoid = false;
if (_voucher.VoucherID != Guid.Empty)
using (var bi = new VoucherBI())
{
var dbVoucher = bi.Get(x => x.VoucherID == _voucher.VoucherID);
isPrinted = dbVoucher.Printed;
isVoid = dbVoucher.Void;
}
if (isVoid)
{
MessageBox.Show(string.Format("This Bill is already void.\nReason: {0}", _voucher.VoidReason), "Bill already Voided", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
if (isPrinted)
{
MessageBox.Show(string.Format("This Bill is already printed and a kot cannot be added", _voucher.VoidReason), "Bill already Printed", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
if (_voucher.VoucherID != Guid.Empty && IsPrintedOrVoid(_voucher))
return;
if (_bill.Count == 1) //new kot only
return;
return false;
#endregion
//Save
@ -461,15 +390,16 @@ namespace Tanshu.Accounts.PointOfSale
if (_editVoucherID.HasValue)
_saleForm.CloseWindow();
else
{
ClearBill();
}
return true;
}
public void SaveBill()
public bool SaveAndPrintBill()
{
#region Check if Allowed
if (!Session.IsAllowed("Print Bill"))
return;
if (_bill.Count == 1) //new kot only
return;
if (!Session.IsAllowed("Print Bill") || _bill.Count(x => x.Key.BillItemType == BillItemType.Product) == 0)
return false;
bool isPrinted = false, isVoid = false;
if (_voucher.VoucherID != Guid.Empty)
using (var bi = new VoucherBI())
@ -481,10 +411,10 @@ namespace Tanshu.Accounts.PointOfSale
if (isVoid)
{
MessageBox.Show(string.Format("This Bill is already void.\nReason: {0}", _voucher.VoidReason), "Bill already Voided", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
return false;
}
if (isPrinted && !Session.IsAllowed("Edit Printed Bill"))
return;
return false;
#endregion
var amount = _bill.NetAmount;
@ -501,15 +431,19 @@ namespace Tanshu.Accounts.PointOfSale
{
frm.ShowDialog();
if (!frm.Selection.HasValue)
return;
return false;
_voucher.VoucherType = frm.Selection.Value;
}
var saved = _voucher.VoucherID == Guid.Empty ? InsertVoucher(true, !_editVoucherID.HasValue) : UpdateVoucher(true, !_editVoucherID.HasValue);
if (_voucher.VoucherID == Guid.Empty)
InsertVoucher(true, !_editVoucherID.HasValue);
else
UpdateVoucher(true, !_editVoucherID.HasValue);
}
Thermal.PrintBill(_voucher.VoucherID);
if (_editVoucherID.HasValue)
_saleForm.CloseWindow();
ClearBill();
return true;
}
public void SplitBill()
{
@ -559,9 +493,8 @@ namespace Tanshu.Accounts.PointOfSale
return;
#region new voucherFirst
var voucherFirst = new Voucher(Session.User)
var voucherFirst = new Voucher(Session.User, _voucher.Customer)
{
Customer = _voucher.Customer,
Table = table,
Printed = isPrinted,
Void = false,
@ -575,9 +508,8 @@ namespace Tanshu.Accounts.PointOfSale
#endregion
#region new voucherSecond
var voucherSecond = new Voucher(Session.User)
var voucherSecond = new Voucher(Session.User, _voucher.Customer)
{
Customer = _voucher.Customer,
Table = _voucher.Table,
Printed = isPrinted,
Void = false,
@ -604,36 +536,31 @@ namespace Tanshu.Accounts.PointOfSale
}
LoadBill(voucherFirst.VoucherID);
}
public void VoidBill()
public bool VoidBill()
{
#region Check conditions and Permissions
if (_voucher.VoucherID == Guid.Empty)
return;
if (_voucher.Void)
return;
if (!Session.IsAllowed("Void Bill"))
return;
if (_voucher.VoucherID == Guid.Empty || _voucher.Void || !Session.IsAllowed("Void Bill"))
return false;
if (MessageBox.Show("Are you sure you want to void this bill?", "Void Bill", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) != DialogResult.Yes)
return;
return false;
#endregion
var voidReason = new SelectVoidReason(GetVoidReason, true);
voidReason.ShowDialog();
if (voidReason.SelectedItem != null)
{
using (var bi = new VoucherBI())
{
bi.VoidBill(_voucher.VoucherID, voidReason.SelectedItem.Description);
if (!_editVoucherID.HasValue)
bi.UpdateTable(x => x.FoodTableID == _voucher.Table.FoodTableID && x.VoucherID == _voucher.VoucherID, null, null);
bi.SaveChanges();
}
ClearBill();
}
else
{
MessageBox.Show("Please Select a reason if you want to void the bill", "Bill NOT Voided", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
return false;
}
using (var bi = new VoucherBI())
{
bi.VoidBill(_voucher.VoucherID, voidReason.SelectedItem.Description);
if (!_editVoucherID.HasValue)
bi.UpdateTable(x => x.FoodTableID == _voucher.Table.FoodTableID && x.VoucherID == _voucher.VoucherID, null, null);
bi.SaveChanges();
}
ClearBill();
return true;
}
private static List<StringType> GetVoidReason(Dictionary<string, string> filter)
{
@ -658,9 +585,8 @@ namespace Tanshu.Accounts.PointOfSale
if (amountChanged || itemsChanged) // Discount or Products changed
{
#region new voucherFirst
var newVoucher = new Voucher(Session.User)
var newVoucher = new Voucher(Session.User, _voucher.Customer)
{
Customer = _voucher.Customer,
Table = _voucher.Table,
Printed = true,
Void = false,

View File

@ -2,6 +2,7 @@
using Tanshu.Accounts.Contracts;
using Tanshu.Common;
using Tanshu.Accounts.Entities;
using System;
namespace Tanshu.Accounts.PointOfSale
{
@ -55,7 +56,7 @@ namespace Tanshu.Accounts.PointOfSale
{
get
{
return this.Where(x => x.Key.BillItemType != BillItemType.Kot).Sum(i => i.Value.inventory.Amount);
return Math.Round(this.Where(x => x.Key.BillItemType != BillItemType.Kot).Sum(i => i.Value.inventory.Amount));
}
}
}

View File

@ -11,13 +11,7 @@ namespace Tanshu.Accounts.PointOfSale
{
public interface ISaleForm
{
void ClearBill(BillDict bill);
void SetCustomerDisplay(string name);
void CloseWindow();
void ShowAmount(decimal discountAmount, decimal grossAmount, decimal serviceChargeAmount, decimal taxAmount, decimal valueAmount, BillDict bill);
void ShowInfo(Voucher voucher);
void SetUserName(string name);
BindingSource BindingSource { get; }
SaleFormState FormState { set; }
}
}