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 KeyedCollection b1 = new KeyedCollection(); private OrderedDictionary bill = new OrderedDictionary(); int? newBillID; ISaleForm saleForm; private Customer customer = new CustomerBI().GetCustomer(1); 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) { BillHelperFunctions.AddProductToGrid(productID, saleForm.BindingSource, bill); 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() { 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)) item.Value.Discount = 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) { using (RoleBI roleBI = RoleFactoryBI.GetRoleBI(RolesConstants.SALES_EDIT_BILL)) { if ((billInfo != null) && (SaleVoucherBI.IsBillPrinted(billInfo.VoucherID)) && (!roleBI.IsAllowed)) { throw new PermissionException("You do not have the permission to reprint a bill."); } } if (bill.Count != 0) { int? saved; if (billInfo == null) saved = AddNewSale(print, waiterID, tableID); else saved = UpdateSale(print, waiterID, tableID); if (saved.HasValue) { if (newBillID.HasValue) saleForm.CloseWindow(); else PrintBill(print, saved.Value); } ClearBill(); } } private int? AddNewSale(bool finalBill, int waiterID, string tableID) { if (billInfo != null) { MessageBox.Show("Error in AddNewSale, 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(); foreach (BillInventory item in list) { Inventory temp = new Inventory(); if (localList.ContainsKey(item.ProductID)) { temp = localList[item.ProductID]; temp.Quantity += item.Quantity; foreach (var mod in item.Modifiers) temp.InventoryModifier.Add(new InventoryModifier() { Modifier = mod }); } else { temp.Discount = item.Discount; temp.Product = ProductBI.GetProduct(item.ProductID); temp.Quantity = item.Quantity; temp.Rate = item.Price; temp.Tax = item.Tax; foreach (var mod in item.Modifiers) temp.InventoryModifier.Add(new InventoryModifier() { Modifier = mod }); localList.Add(item.ProductID, temp); } } return localList.Values.ToList(); } public decimal GetInput(string type, decimal basic) { decimal value; InputBoxResult result = InputBox.Show(type, basic.ToString(), InputBox_Validating); if (result.OK) { if (!decimal.TryParse(result.Text, out value)) return 0; return value; } return 0; } #endregion public void VoidBill() { if (billInfo == null) return; if (!billInfo.Printed) return; using (RoleBI roleBI = RoleFactoryBI.GetRoleBI(RolesConstants.SALES_VOID_BILL)) { if (roleBI.IsAllowed) { 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); } } } else throw new PermissionException("You do not have the permission to void a bill."); } } 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) { using (RoleBI roleBI = RoleFactoryBI.GetRoleBI(RolesConstants.SALES_PRINT_KOT)) if (!roleBI.IsAllowed) throw new PermissionException("You are not allowed to print KOT"); if (!finalBill) Accounts.Print.Thermal.PrintKot(voucherID, bill.Values.ToList()); else { using (RoleBI roleBI = RoleFactoryBI.GetRoleBI(RolesConstants.SALES_PRINT_BILL)) { if (roleBI.IsAllowed) { Accounts.Print.Thermal.PrintBill(true, voucherID, bill.Values.ToList()); } else throw new PermissionException("You are not allowed to print KOT"); } } } 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 void SetNewBillID(int voucherID) { this.newBillID = voucherID; } public BillInventory CurrentProduct { get { 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 SetDiscount(BillInventory billInventory, decimal discount) { if (billInventory == null) return; BillHelperFunctions.SetDiscount(billInventory.ProductID, discount, customer, bill); ShowAmount(); } public void SetAmount(BillInventory billInventory, decimal amount) { if (billInventory == null) return; BillHelperFunctions.SetAmount(billInventory, amount, saleForm.BindingSource, bill); ShowAmount(); } public void ProductRemove(BillInventory billInventory) { if (billInventory == null) return; if (billInventory.Printed > 0) { using (RoleBI roleBI = RoleFactoryBI.GetRoleBI(RolesConstants.SALES_EDIT_PRINTED_PRODUCT)) { if (roleBI.IsAllowed) { if (MessageBox.Show(string.Format("Already {0} items have been printed.\n\rAre you sure you want to delete this item?", billInventory.Printed), "Delete", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) return; } } } bill.Remove(new BillItemKey(billInventory.ProductID, billInventory.Printed == 0)); bill.ReCompact(); ShowAmount(); } public void SetQuantity(BillInventory billInventory, decimal quantity, bool absolute, bool prompt) { if (billInventory == null) return; BillHelperFunctions.SetQuantity(billInventory, quantity, absolute, prompt, saleForm.BindingSource, bill); ShowAmount(); } public void ChangeRate() { var item = CurrentProduct; if (item != null) { decimal rate = 0; InputBoxResult result = InputBox.Show("Rate", item.Price.ToString(), InputBox_Validating); if (result.OK) rate = Convert.ToDecimal(result.Text); if (rate != 0) { BillHelperFunctions.SetRate(item.ProductID, rate, bill); ShowAmount(); } } } 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) if (MessageBox.Show("Cancel current bill?", "Cancel bill", 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 (newBillID.HasValue) { LoadBill(newBillID.Value); } } internal void SettleBill() { if (billInfo == null) return; if (!billInfo.Printed) 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).voucherID); // ChangeFormState(SaleFormState.Billing);