using System; using System.Collections.Generic; using System.Linq; using System.Text; using Tanshu.Accounts.Repository; using Tanshu.Accounts.Helpers; using Tanshu.Accounts.Contracts; using System.Windows.Forms; using Tanshu.Common; using Tanshu.Accounts.Entities; using Tanshu.Accounts.Entities.Auth; using Tanshu.Accounts.SqlDAO; using System.Collections.ObjectModel; namespace Tanshu.Accounts.PointOfSale { public class BillController { private SaleVoucher billInfo; private OrderedDictionary bill = new OrderedDictionary(); int? editVoucherID; ISaleForm saleForm; private Customer customer = new CustomerBI().GetCustomer(1); public BillController(int? editVoucherID) { this.editVoucherID = editVoucherID; } public void InitGui(ISaleForm saleForm) { this.saleForm = saleForm; this.saleForm.SetCustomerDisplay(customer.Name); this.saleForm.SetUserName(Session.User.Name); } private void InitComponents() { InitModel(); InitView(); } private void InitView() { throw new NotImplementedException(); } private void InitModel() { throw new NotImplementedException(); } public void AddProductToGrid(int productID) { new BillHelperFunctions(saleForm.BindingSource, bill, productID).AddProduct(); Product product = ProductBI.GetProduct(productID); if (ProductGroupModifierBI.HasCompulsoryModifier(product.ProductGroup.ProductGroupID)) { var item = CurrentProduct; ShowModifiers(product.ProductGroup.ProductGroupID, item); } ShowAmount(); } public void ShowModifiers(int productGroupID, BillInventory item) { if (item.Printed > 0) return; var list = ProductGroupModifierBI.GetProductGroupModifiers(productGroupID); using (var frm = new ModifierForm(list, item.Modifiers)) { frm.ShowDialog(); item.Modifiers = frm.Selection; } ShowAmount(); } public void ShowDiscount() { if (!Session.IsAllowed(RoleConstants.DISCOUNT)) return; var list = new ProductGroupBI().GetProductGroups(); using (var frm = new DiscountForm(list)) { if (frm.ShowDialog() == DialogResult.OK) { IList outList; decimal discount = frm.Selection(out outList); discount = discount / 100; foreach (var item in bill) { var pg = new ProductGroupBI().GetProductGroupOfProduct(item.Value.ProductID); if (outList.Contains(pg.ProductGroupID)) new BillHelperFunctions(saleForm.BindingSource, bill, item.Value.ProductID).SetDiscount(item.Value.Name, discount); } } } ShowAmount(); } public void ShowCustomerList(bool reset) { if ((customer.CustomerID == 1) && (!reset)) { using (SelectCustomer selectCustomer = new SelectCustomer(new CustomerBI().GetFilteredCustomers, true)) { selectCustomer.customerEvent += new CustomerEventHandler(selectCustomer_customerEvent); selectCustomer.ShowDialog(); if (selectCustomer.SelectedItem != null) { customer = selectCustomer.SelectedItem; saleForm.SetCustomerDisplay(customer.Name); } else { customer = new CustomerBI().GetCustomer(1); } } } else { customer = new CustomerBI().GetCustomer(1); saleForm.SetCustomerDisplay(customer.Name); } } #region Save // if (btnWaiter.Tag == null) //btnWaiter.Tag = WaiterBI.GetWaiters()[0].WaiterID; public void Save(bool print, int waiterID, string tableID) { if (print && !Session.IsAllowed(RoleConstants.PRINT_BILL)) return; if (!print && !Session.IsAllowed(RoleConstants.PRINT_KOT)) return; if ((billInfo != null) && (SaleVoucherBI.IsBillPrinted(billInfo.VoucherID)) && (!Session.IsAllowed(RoleConstants.EDIT_PRINTED_BILL))) return; if (bill.Count == 0) return; int? saved; if (billInfo == null) saved = InsertVoucher(print, waiterID, tableID); else saved = UpdateSale(print, waiterID, tableID); if (saved.HasValue) { if (editVoucherID.HasValue) saleForm.CloseWindow(); else PrintBill(print, saved.Value); } ClearBill(); } private int? InsertVoucher(bool finalBill, int waiterID, string tableID) { if (billInfo != null) { MessageBox.Show("Error in InsertVoucher, there is a previous sale in memory", "Error"); return null; } #region SaleVoucher SaleVoucher saleVoucher = new SaleVoucher { Customer = customer, Settled = SettleOptionBI.GetSettleOption(SettleOptionFactory.Unsettled), //Paid = finalBill, TableID = tableID, Waiter = WaiterBI.GetWaiter(waiterID), Printed = finalBill, Void = false, Date = DateTime.Now, Narration = "", Ref = "", Type = 'S', User = Session.User }; #endregion #region Inventories IList iList = GetInventoryForBill(bill.Values); #endregion SaleVoucherBI.Insert(saleVoucher, iList); return saleVoucher.VoucherID; } private int? UpdateSale(bool finalBill, int waiterID, string tableID) { #region SaleVoucher billInfo.User = Session.User; billInfo.Customer = customer; if (!billInfo.Printed && finalBill) billInfo.Date = null; billInfo.Printed = billInfo.Printed || finalBill; billInfo.TableID = tableID; billInfo.Waiter = WaiterBI.GetWaiter(waiterID); //if ((!billInfo.Printed) && finalBill) // billInfo.Date = null; billInfo.Inventories = new List(); #endregion #region Inventory IList iList = GetInventoryForBill(bill.Values); #endregion SaleVoucherBI.Update(billInfo, iList); return billInfo.VoucherID; } private IList GetInventoryForBill(ICollection list) { Dictionary localList = new Dictionary(); HashSet keys = new HashSet(); foreach (BillInventory item in list) { Inventory temp = new Inventory(); if (localList.ContainsKey(item.ProductID)) { if (temp.Quantity <= 0) keys.Remove(item.ProductID); temp = localList[item.ProductID]; temp.Quantity += item.Quantity; temp.Amount += item.Value; foreach (var mod in item.Modifiers) temp.InventoryModifier.Add(new InventoryModifier() { Modifier = mod }); if (temp.Quantity <= 0) keys.Add(item.ProductID); } else { temp.Product = ProductBI.GetProduct(item.ProductID); temp.Quantity = item.Quantity; temp.Rate = item.Price; temp.Discount = item.Discount; temp.ServiceCharge = item.ServiceCharge; temp.Tax = item.Tax; temp.Amount = item.Value; foreach (var mod in item.Modifiers) temp.InventoryModifier.Add(new InventoryModifier() { Modifier = mod }); localList.Add(item.ProductID, temp); if (item.Quantity <= 0) keys.Add(item.ProductID); } } foreach (var item in keys) { localList.Remove(item); } return localList.Values.ToList(); } #endregion public void VoidBill() { if (billInfo == null) return; if (!billInfo.Printed) return; if (Session.IsAllowed(RoleConstants.VOID_BILL)) { if (MessageBox.Show("Are you sure you want to void this bill?", "Void Bill", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes) { SelectVoidReason voidReason = new SelectVoidReason(GetVoidReason, true); voidReason.ShowDialog(); if (voidReason.SelectedItem != null) { SaleVoucherBI.VoidBill(billInfo.VoucherID, voidReason.SelectedItem.Description); ClearBill(); } else { MessageBox.Show("Please Select a reason if you want to void the bill", "Bill NOT Voided", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); } } } } Customer selectCustomer_customerEvent(object sender, CustomerEventArgs e) { using (CustomersForm form = new CustomersForm(e.CustomerID, e.Phone)) { form.ShowDialog(); return form.Customer; } } private void PrintBill(bool finalBill, int voucherID) { if (!finalBill) Accounts.Print.Thermal.PrintKot(voucherID, bill.Values.ToList()); else Accounts.Print.Thermal.PrintBill(voucherID, bill.Values.ToList()); } private List GetVoidReason(Dictionary filter) { List list = new List(); list.Add(new StringType("Discount")); list.Add(new StringType("Printing Fault")); list.Add(new StringType("Item Changed")); list.Add(new StringType("Quantity Reduced")); list.Add(new StringType("Costing Bill for Party")); list.Add(new StringType("Cashier Mistake")); list.Add(new StringType("Management Freesale")); list.Add(new StringType("Other")); return list.Where(i => i.Description.ToLower().Contains(filter["Name"].ToLower().Trim())).ToList(); } public BillInventory CurrentProduct { get { if (saleForm.BindingSource.Position == -1) return null; else return bill.ElementAt(saleForm.BindingSource.Position).Value; } } private void ShowAmount() { //saleForm.BindingSource.CurrencyManager.Position = 1; decimal taxAmount = bill.Values.Sum(b => b.TaxAmount); decimal discountAmount = bill.Values.Sum(b => b.DiscountAmount); decimal grossAmount = bill.Values.Sum(b => b.GrossAmount); decimal valueAmount = bill.Values.Sum(b => b.Value); decimal serviceChargeAmount = bill.Values.Sum(b => b.ServiceChargeAmount); //bill.Values.ToList(); saleForm.ShowAmount(discountAmount, grossAmount, serviceChargeAmount, taxAmount, valueAmount, bill.Values.ToList()); } public void ProductRemove() { var item = CurrentProduct; if (!Allowed(item)) return; if (item.Printed > 0) { if (!Session.IsAllowed(RoleConstants.EDIT_PRINTED_PRODUCT)) return; else if (MessageBox.Show(string.Format("Already {0} items have been printed.\n\rAre you sure you want to delete this item?", item.Printed), "Delete", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) return; } bill.Remove(new BillItemKey(item.ProductID, item.Printed == 0)); bill.ReCompact(); ShowAmount(); } public void SetQuantity(decimal quantity, bool prompt) { var item = CurrentProduct; if (!Allowed(item)) return; new BillHelperFunctions(saleForm.BindingSource, bill, CurrentProduct.ProductID).SetQuantity(item, quantity, prompt); ShowAmount(); } public void ChangeRate() { new BillHelperFunctions(saleForm.BindingSource, bill, CurrentProduct.ProductID).SetPrice(CurrentProduct); ShowAmount(); } private bool Allowed(BillInventory item, RoleConstants role) { if (item == null) return false; if (!Session.IsAllowed(role)) return false; return true; } private bool Allowed(BillInventory item) { return item != null; } private void InputBox_Validating(object sender, InputBoxValidatingArgs e) { } private void LoadBill(int voucherID) { ClearBill(); IList iList = new List(); SaleVoucherBI.GetSaleVoucher(voucherID, out billInfo, out iList); this.customer = billInfo.Customer; saleForm.ShowInfo(billInfo.BillID, billInfo.KotID, billInfo.CreationDate, billInfo.Date.Value, billInfo.LastEditDate, customer.Name, billInfo.TableID, billInfo.Waiter.WaiterID, billInfo.Waiter.Name); foreach (Inventory inventory in iList) { BillItemKey key = new BillItemKey(inventory.Product.ProductID, false); var product = ProductBI.GetProduct(inventory.Product.ProductID); var item = new BillInventory { ProductID = product.ProductID, Discount = inventory.Discount, Name = product.Units == string.Empty ? product.Name : product.Name + " (" + product.Units + ")", Price = inventory.Rate, Printed = inventory.Quantity, Quantity = inventory.Quantity, Tax = inventory.Tax, ServiceCharge = inventory.ServiceCharge, }; foreach (var mod in inventory.InventoryModifier) item.Modifiers.Add(mod.Modifier); bill.Add(key, item); } ShowAmount(); } public void LoadBillFromTable(string tableName) { if (!string.IsNullOrEmpty(tableName)) { SaleVoucher voucher = SaleVoucherBI.GetPendingVoucherID(tableName); if (voucher != null) { LoadBill(voucher.VoucherID); } } else { InputBoxResult result = InputBox.Show("Table Number", "0", InputBox_Validating); if (result.OK) { string tableID = result.Text.Trim(); if ((tableID != "C") && (tableID != "") && (!tableID.Contains("."))) { SaleVoucher voucher = SaleVoucherBI.GetPendingVoucherID(tableName); if (voucher != null) { LoadBill(voucher.VoucherID); } } else ClearBill(); } } } public void CancelBillChanges() { if (bill.Count != 0 && bill.Values.Any(i => i.Printed != i.Quantity)) if (MessageBox.Show("Abandon Changes?", "Abandon Changes", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.No) return; ClearBill(); } public void ClearBill() { billInfo = null; ShowCustomerList(true); bill.Clear(); saleForm.ClearBill(bill); } public void FormLoad() { if (editVoucherID.HasValue) { LoadBill(editVoucherID.Value); } } internal void SettleBill() { if (billInfo == null) return; if (!billInfo.Printed) return; if (!Session.IsAllowed(RoleConstants.SETTLE_BILL)) return; int option = SettleOptionFactory.Unsettled; using (BillSettleForm frm = new BillSettleForm()) { frm.ShowDialog(); option = frm.optionChosen; } if (option != SettleOptionFactory.Unsettled) { SaleVoucherBI.SettleVoucher(Session.User, billInfo.VoucherID, option); ClearBill(); } } } } // How to load a bill //LoadBill(((PendingBills)bsPending.Current).editVoucherID); // ChangeFormState(SaleFormState.Billing);