2d1030abf6
Changed inventory and product entities to split Vat and Service Tax and IsScTaxable. Added MessageBox on startup to inform about Debug Mode. Updated ProductForm for the change. Work still needs to be done on Thermal Printing where the hack for VAT on Food and VAT on Liqour is still there. Now No Service Tax on Delivery Works as promised.
1013 lines
38 KiB
C#
1013 lines
38 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Windows.Forms;
|
|
using Tanshu.Accounts.Contracts;
|
|
using Tanshu.Accounts.Entities;
|
|
using Tanshu.Accounts.Helpers;
|
|
using Tanshu.Accounts.Print;
|
|
using Tanshu.Accounts.Repository;
|
|
using Tanshu.Common;
|
|
|
|
namespace Tanshu.Accounts.PointOfSale
|
|
{
|
|
public class BillController
|
|
{
|
|
private readonly OrderedDictionary<BillItemKey, BillItemValue> _bill;
|
|
|
|
private Voucher _billInfo;
|
|
|
|
private int? _editVoucherID;
|
|
private readonly bool _print;
|
|
|
|
private ISaleForm _saleForm;
|
|
|
|
public Waiter Waiter
|
|
{
|
|
get { return _billInfo.Waiter; }
|
|
set { _billInfo.Waiter = value; }
|
|
}
|
|
|
|
public BillController(int? editVoucherID, bool print)
|
|
{
|
|
this._editVoucherID = editVoucherID;
|
|
_print = print;
|
|
_bill = new OrderedDictionary<BillItemKey, BillItemValue>();
|
|
_billInfo = new Voucher(Session.User);
|
|
using (var bi = new CustomerBI(false))
|
|
_billInfo.Customer = bi.Get(x => x.CustomerID == 1);
|
|
using (var bi = new WaiterBI(false))
|
|
_billInfo.Waiter = bi.Get(x => x.WaiterID == 1);
|
|
}
|
|
|
|
public BillItemValue CurrentProduct
|
|
{
|
|
get
|
|
{
|
|
if (_saleForm.BindingSource.Position == -1)
|
|
return null;
|
|
var item = _bill.ElementAt(_saleForm.BindingSource.Position);
|
|
return item.Key.BillItemType == BillItemType.Product ? item.Value : null;
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
public void InitGui(ISaleForm saleForm)
|
|
{
|
|
this._saleForm = saleForm;
|
|
this._saleForm.SetCustomerDisplay(_billInfo.Customer.Name);
|
|
this._saleForm.SetUserName(Session.User.Name);
|
|
}
|
|
|
|
public void AddProduct(Product product)
|
|
{
|
|
var newKey = new BillItemKey(product.ProductID, 0);
|
|
|
|
if (_bill.ContainsKey(newKey))
|
|
{
|
|
_saleForm.BindingSource.CurrencyManager.Position = _bill.IndexOfKey(newKey);
|
|
_bill[newKey].Quantity += 1;
|
|
}
|
|
else
|
|
{
|
|
var billItemValue = new BillItemValue(product);
|
|
var old =
|
|
_bill.Where(x => x.Key.BillItemType == BillItemType.Product && x.Key.ProductID == newKey.ProductID).
|
|
FirstOrDefault();
|
|
if (old.Key != null)
|
|
{
|
|
billItemValue.Discount = old.Value.Discount;
|
|
billItemValue.Price = old.Value.Price;
|
|
}
|
|
_bill.Add(newKey, billItemValue);
|
|
_saleForm.BindingSource.DataSource = _bill.Values.ToList();
|
|
_saleForm.BindingSource.CurrencyManager.Position = _saleForm.BindingSource.CurrencyManager.Count - 1;
|
|
|
|
using (var bi = new ProductGroupModifierBI(false))
|
|
if (bi.HasCompulsoryModifier(product.ProductGroup.ProductGroupID))
|
|
{
|
|
var item = CurrentProduct;
|
|
ShowModifiers(product.ProductGroup.ProductGroupID, item);
|
|
}
|
|
}
|
|
ShowAmount();
|
|
}
|
|
|
|
public void ShowModifiers(int productGroupID, BillItemValue item)
|
|
{
|
|
if (item.Printed)
|
|
return;
|
|
using (var bi = new ProductGroupModifierBI(false))
|
|
{
|
|
using (var frm = new ModifierForm(bi.List(productGroupID), item.Modifiers))
|
|
{
|
|
frm.ShowDialog();
|
|
item.Modifiers = frm.Selection;
|
|
}
|
|
}
|
|
ShowAmount();
|
|
}
|
|
|
|
public void SetDiscount()
|
|
{
|
|
if (!Session.IsAllowed(RoleConstants.DISCOUNT))
|
|
return;
|
|
|
|
using (var bi = new ProductGroupBI())
|
|
{
|
|
using (var frm = new DiscountForm(bi.GetProductGroupTypes()))
|
|
{
|
|
if (frm.ShowDialog() == DialogResult.OK)
|
|
{
|
|
HashSet<string> outList;
|
|
var discount = frm.Selection(out outList);
|
|
discount = discount / 100;
|
|
if (discount > 1 || discount < 0)
|
|
return;
|
|
|
|
foreach (var item in _bill.Where(x => x.Key.BillItemType == BillItemType.Product && outList.Contains(x.Value.Product.ProductGroup.GroupType)))
|
|
{
|
|
var product = item.Value.Product;
|
|
var maxDiscount = product.ProductGroup.DiscountLimit;
|
|
if (discount > item.Value.Product.ProductGroup.DiscountLimit)
|
|
MessageBox.Show(string.Format("Maximum discount for {0} is {1:P}", product.Name, maxDiscount),
|
|
"Excessive Discount", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
item.Value.Discount = discount;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
ShowAmount();
|
|
}
|
|
|
|
public void SetQuantity(decimal quantity, bool prompt)
|
|
{
|
|
var item = CurrentProduct;
|
|
if (!Allowed(item))
|
|
return;
|
|
if (item.Printed)
|
|
return;
|
|
if (prompt && !GetInput("Quantity", ref quantity))
|
|
return;
|
|
if (!prompt)
|
|
quantity += item.Quantity;
|
|
if (quantity < 0 && !Session.IsAllowed(RoleConstants.EDIT_PRINTED_PRODUCT))
|
|
return;
|
|
var total = quantity + _bill.Where(x => x.Key.ProductID == item.ProductID && x.Key.BillItemType == BillItemType.Product && x.Value.Printed).Sum(x => x.Value.Quantity);
|
|
if (total < 0)
|
|
quantity -= total;
|
|
item.Quantity = quantity;
|
|
ShowAmount();
|
|
}
|
|
|
|
public void SetRate()
|
|
{
|
|
var item = CurrentProduct;
|
|
if (!Allowed(item, RoleConstants.CHANGE_RATE))
|
|
return;
|
|
var rate = item.Price;
|
|
if (!GetInput("Price", ref rate))
|
|
return;
|
|
if (rate == 0 && !Session.IsAllowed(RoleConstants.ZERO_RATE))
|
|
return;
|
|
foreach (var sub in _bill.Where(x => x.Key.BillItemType == BillItemType.Product && x.Key.ProductID == item.ProductID))
|
|
sub.Value.Price = rate;
|
|
|
|
ShowAmount();
|
|
}
|
|
|
|
public void ShowCustomers(bool reset)
|
|
{
|
|
if (!reset && ((_billInfo.Customer == null) || _billInfo.Customer.CustomerID == 1))
|
|
{
|
|
using (var selectCustomer = new SelectCustomer(CustomerBI.List, true))
|
|
{
|
|
selectCustomer.CustomerEvent += selectCustomer_customerEvent;
|
|
selectCustomer.ShowDialog();
|
|
if (selectCustomer.SelectedItem != null)
|
|
{
|
|
_billInfo.Customer = selectCustomer.SelectedItem;
|
|
}
|
|
else
|
|
{
|
|
using (var bi = new CustomerBI(false))
|
|
_billInfo.Customer = bi.Get(x => x.CustomerID == 1);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
using (var bi = new CustomerBI(false))
|
|
_billInfo.Customer = bi.Get(x => x.CustomerID == 1);
|
|
}
|
|
_saleForm.SetCustomerDisplay(_billInfo.Customer.Name);
|
|
}
|
|
|
|
private Customer selectCustomer_customerEvent(object sender, CustomerEventArgs e)
|
|
{
|
|
using (var form = new CustomersForm(e.CustomerID, e.Phone))
|
|
{
|
|
form.ShowDialog();
|
|
return form.Customer;
|
|
}
|
|
}
|
|
|
|
public void ShowWaiters(bool reset)
|
|
{
|
|
if (reset)
|
|
{
|
|
using (var bi = new WaiterBI(false))
|
|
_billInfo.Waiter = bi.Get(x => x.WaiterID == 1);
|
|
}
|
|
else
|
|
{
|
|
using (var selectWaiter = new SelectWaiter(WaiterBI.List, true))
|
|
{
|
|
selectWaiter.WaiterEvent += selectWaiter_waiterEvent;
|
|
selectWaiter.ShowDialog();
|
|
if (selectWaiter.SelectedItem != null)
|
|
{
|
|
_billInfo.Waiter = selectWaiter.SelectedItem;
|
|
|
|
}
|
|
else
|
|
{
|
|
using (var bi = new WaiterBI(false))
|
|
_billInfo.Waiter = bi.Get(x => x.WaiterID == 1);
|
|
}
|
|
}
|
|
}
|
|
_saleForm.SetWaiterDisplay(_billInfo.Waiter.Name);
|
|
}
|
|
|
|
private Waiter selectWaiter_waiterEvent(object sender, SelectorEventArgs<Waiter> e)
|
|
{
|
|
var waiter = e.Item;
|
|
//if (!Thread.CurrentPrincipal.IsInRole("Waiter/Master"))
|
|
// return waiter;
|
|
|
|
using (var bi = new WaiterBI())
|
|
{
|
|
switch (e.Action)
|
|
{
|
|
case SelectorAction.Insert: // Add
|
|
bi.Insert(waiter);
|
|
e.Handled = true;
|
|
return waiter;
|
|
case SelectorAction.Update: // Edit
|
|
bi.Update(waiter);
|
|
e.Handled = true;
|
|
return waiter;
|
|
case SelectorAction.Delete: // Delete
|
|
bi.Delete(x => x.WaiterID == waiter.WaiterID);
|
|
e.Handled = true;
|
|
return bi.Get(x => x.WaiterID == 1);
|
|
default:
|
|
e.Handled = true;
|
|
return bi.Get(x => x.WaiterID == 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ShowAmount()
|
|
{
|
|
var taxAmount = _bill.Values.Sum(b => b.ServiceTaxAmount + b.VatAmount);
|
|
var discountAmount = _bill.Values.Sum(b => b.DiscountAmount);
|
|
var grossAmount = _bill.Values.Sum(b => b.GrossAmount);
|
|
var valueAmount = _bill.Values.Sum(b => b.Value);
|
|
var serviceChargeAmount = _bill.Values.Sum(b => b.ServiceChargeAmount);
|
|
_saleForm.ShowAmount(discountAmount, grossAmount, serviceChargeAmount, taxAmount, valueAmount,
|
|
_bill.Values.ToList());
|
|
}
|
|
|
|
//public void ProductRemove()
|
|
//{
|
|
// var item = CurrentProduct;
|
|
// if (!Allowed(item))
|
|
// return;
|
|
// if (item.Printed)
|
|
// return;
|
|
// _bill.Remove(new BillItemKey(item.ProductID, 0));
|
|
// _bill.ReCompact();
|
|
// ShowAmount();
|
|
//}
|
|
|
|
|
|
private static bool Allowed(BillItemValue item, RoleConstants role)
|
|
{
|
|
return item != null && Session.IsAllowed(role);
|
|
}
|
|
|
|
private static bool Allowed(BillItemValue item)
|
|
{
|
|
return item != null;
|
|
}
|
|
|
|
private static void IsPrintedOrVoid(Voucher voucher, out bool isPrinted, out bool isVoid)
|
|
{
|
|
using (var bi = new VoucherBI(false))
|
|
{
|
|
var dbVoucher = bi.Get(x => x.VoucherID == voucher.VoucherID);
|
|
isPrinted = dbVoucher.Printed;
|
|
isVoid = dbVoucher.Void;
|
|
}
|
|
}
|
|
|
|
private static bool IsPrintedOrVoid(Voucher voucher)
|
|
{
|
|
using (var bi = new VoucherBI(false))
|
|
{
|
|
var dbVoucher = bi.Get(x => x.VoucherID == voucher.VoucherID);
|
|
return dbVoucher.Printed || dbVoucher.Void;
|
|
}
|
|
}
|
|
|
|
private static bool IsPrintedOrVoid(int voucherID)
|
|
{
|
|
using (var bi = new VoucherBI(false))
|
|
{
|
|
var dbVoucher = bi.Get(x => x.VoucherID == voucherID);
|
|
return dbVoucher.Printed || dbVoucher.Void;
|
|
}
|
|
}
|
|
|
|
private bool? IsReprint(out decimal amount)
|
|
{
|
|
amount = 0;
|
|
if (_billInfo.VoucherID == 0)
|
|
return false;
|
|
|
|
bool isPrinted, isVoid;
|
|
IsPrintedOrVoid(_billInfo, out isPrinted, out isVoid);
|
|
|
|
if (isVoid)
|
|
{
|
|
MessageBox.Show(string.Format("This Bill is already void.\nReason: {0}", _billInfo.VoidReason), "Bill already Voided", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
return null;
|
|
}
|
|
|
|
if (isPrinted && (!Session.IsAllowed(RoleConstants.EDIT_PRINTED_BILL)))
|
|
return null;
|
|
amount = _bill.Where(x => x.Key.BillItemType == BillItemType.Product && x.Key.KotID != 0).Sum(x => x.Value.GrossAmount);
|
|
|
|
return isPrinted;
|
|
}
|
|
|
|
private void InputBox_Validating(object sender, InputBoxValidatingArgs e)
|
|
{
|
|
}
|
|
|
|
private void LoadBill(int voucherID)
|
|
{
|
|
ClearBill();
|
|
using (var bi = new VoucherBI(false))
|
|
{
|
|
_billInfo = bi.Get(x => x.VoucherID == voucherID);
|
|
_bill.Clear();
|
|
_saleForm.ShowInfo(_billInfo);
|
|
|
|
foreach (var kot in _billInfo.Kots)
|
|
{
|
|
var kotKey = new BillItemKey(kot.KotID);
|
|
var kotItem = new BillItemValue(kot);
|
|
_bill.Add(kotKey, kotItem);
|
|
foreach (var inv in kot.Inventories)
|
|
{
|
|
var key = new BillItemKey(inv.Product.ProductID, kot.KotID);
|
|
var item = new BillItemValue(inv.Product)
|
|
{
|
|
ProductID = inv.Product.ProductID,
|
|
Discount = inv.Discount,
|
|
Name =
|
|
inv.Product.Units == string.Empty
|
|
? inv.Product.Name
|
|
: inv.Product.Name + " (" + inv.Product.Units + ")",
|
|
Price = inv.Price,
|
|
Printed = true,
|
|
Quantity = inv.Quantity,
|
|
IsScTaxable = inv.IsScTaxable,
|
|
ServiceTax = inv.ServiceTax,
|
|
Vat = inv.Vat,
|
|
ServiceCharge = inv.ServiceCharge,
|
|
};
|
|
foreach (var mod in inv.InventoryModifier)
|
|
item.Modifiers.Add(mod.Modifier);
|
|
_bill.Add(key, item);
|
|
}
|
|
}
|
|
var newKotKey = new BillItemKey(0);
|
|
var newKotItem = new BillItemValue();
|
|
_bill.Add(newKotKey, newKotItem);
|
|
ShowAmount();
|
|
_saleForm.FormState = SaleFormState.Billing;
|
|
}
|
|
}
|
|
|
|
public void LoadBill(string tableName)
|
|
{
|
|
if (!string.IsNullOrEmpty(tableName))
|
|
{
|
|
FoodTable table;
|
|
using (var bi = new FoodTableBI())
|
|
table = bi.Get(x => x.Name == tableName);
|
|
if (table != null && table.VoucherID != 0)
|
|
{
|
|
LoadBill(table.VoucherID);
|
|
}
|
|
else
|
|
{
|
|
using (var frm = new PaxForm())
|
|
{
|
|
frm.ShowDialog();
|
|
_billInfo.TableID = tableName;
|
|
_billInfo.Pax = frm.Pax;
|
|
_saleForm.ShowInfo(_billInfo);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var result = "0";
|
|
if (GetInput("Table Number", ref result))
|
|
LoadBill(result);
|
|
else
|
|
ClearBill();
|
|
}
|
|
}
|
|
|
|
public void CancelBillChanges()
|
|
{
|
|
if (_bill.Values.Any(i => i.Printed == false) &&
|
|
MessageBox.Show("Abandon Changes?", "Abandon Changes", MessageBoxButtons.YesNo,
|
|
MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.No)
|
|
return;
|
|
ClearBill();
|
|
}
|
|
|
|
public void ClearBill()
|
|
{
|
|
_billInfo = new Voucher(Session.User);
|
|
ShowCustomers(true);
|
|
ShowWaiters(true);
|
|
_bill.Clear();
|
|
var newKotKey = new BillItemKey(0);
|
|
var newKotItem = new BillItemValue();
|
|
_bill.Add(newKotKey, newKotItem);
|
|
_saleForm.ClearBill(_bill.Values.ToList());
|
|
}
|
|
|
|
public SaleFormState FormLoad()
|
|
{
|
|
ClearBill();
|
|
if (_editVoucherID.HasValue)
|
|
{
|
|
LoadBill(_editVoucherID.Value);
|
|
return SaleFormState.Billing;
|
|
}
|
|
return SaleFormState.Waiting;
|
|
}
|
|
|
|
internal void SettleBill()
|
|
{
|
|
if (_billInfo.VoucherID == 0)
|
|
return;
|
|
if (!_billInfo.Printed)
|
|
return;
|
|
if (!Session.IsAllowed(RoleConstants.SETTLE_BILL))
|
|
return;
|
|
IDictionary<SettleOption, decimal> options;
|
|
var amount = (_billInfo.Settlements.Single(x => x.Settled == SettleOption.Amount).Amount +
|
|
_billInfo.Settlements.Single(x => x.Settled == SettleOption.RoundOff).Amount) * -1;
|
|
|
|
using (var frm = new SettleChoicesForm(amount, _billInfo.VoucherType))
|
|
{
|
|
frm.ShowDialog();
|
|
options = frm.OptionsChosen;
|
|
}
|
|
if (options.Count == 0)
|
|
return;
|
|
using (var bi = new VoucherSettlementBI())
|
|
bi.SettleVoucher(Session.User, _billInfo.VoucherID, options);
|
|
ClearBill();
|
|
}
|
|
|
|
#region Move Table(s) / Kot(s)
|
|
private static FoodTable GetTableForMove(bool allowMerge)
|
|
{
|
|
using (var bi = new FoodTableBI())
|
|
{
|
|
using (var frm = new MoveTableForm(bi.List(), allowMerge))
|
|
{
|
|
frm.ShowDialog();
|
|
if (frm.Selection != null)
|
|
return frm.Selection;
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
internal void MoveKot()
|
|
{
|
|
if (_billInfo.VoucherID == 0)
|
|
return;
|
|
if (IsPrintedOrVoid(_billInfo))
|
|
return;
|
|
var kot = CurrentKot;
|
|
if (kot == null)
|
|
return;
|
|
var table = GetTableForMove(true);
|
|
if (table == null)
|
|
return;
|
|
if (table.Name == _billInfo.TableID)
|
|
return;
|
|
if (table.VoucherID != 0)
|
|
if (IsPrintedOrVoid(table.VoucherID))
|
|
return;
|
|
var kotCount = _bill.Keys.Count(x => x.BillItemType == BillItemType.Kot && x.KotID != 0);
|
|
var voucherID = 0;
|
|
if (table.VoucherID == 0 && kotCount > 1)
|
|
//Move Kot
|
|
voucherID = MoveKot(kot, table);
|
|
else if (table.VoucherID != 0 && kotCount > 1)
|
|
//Merge Kot
|
|
voucherID = MergeKot(kot, table);
|
|
else if (table.VoucherID == 0 && kotCount == 1)
|
|
//Move Table
|
|
voucherID = MoveTable(table);
|
|
else if (table.VoucherID != 0 && kotCount == 1)
|
|
//Merge Table
|
|
voucherID = MergeTable(table);
|
|
if (voucherID != 0)
|
|
LoadBill(voucherID);
|
|
}
|
|
internal void MoveTable()
|
|
{
|
|
if (_billInfo.VoucherID == 0)
|
|
return;
|
|
|
|
var allowMerge = !IsPrintedOrVoid(_billInfo);
|
|
|
|
var table = GetTableForMove(allowMerge);
|
|
if (table == null)
|
|
return;
|
|
if (table.Name == _billInfo.TableID)
|
|
return;
|
|
if (table.VoucherID != 0)
|
|
if (IsPrintedOrVoid(table.VoucherID))
|
|
return;
|
|
|
|
LoadBill(table.VoucherID == 0 ? MoveTable(table) : MergeTable(table));
|
|
}
|
|
|
|
private int MoveKot(BillItemKey kot, FoodTable table)
|
|
{
|
|
if (!Session.IsAllowed(RoleConstants.MOVE_KOT))
|
|
return 0;
|
|
var voucher = new Voucher(Session.User, _billInfo.Customer, table.Name, _billInfo.Waiter, _billInfo.Printed, false, "");
|
|
|
|
using (var session = SessionManager.Session)
|
|
{
|
|
using (var trans = session.BeginTransaction())
|
|
{
|
|
using (var bi = new VoucherBI(session, false))
|
|
{
|
|
bi.Insert(voucher);
|
|
using (var ft = new FoodTableBI(session, false))
|
|
ft.UpdateStatus(voucher);
|
|
var voucherId = bi.MergeKot(kot.KotID, voucher);
|
|
trans.Commit();
|
|
return voucherId;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static int MergeKot(BillItemKey kot, FoodTable table)
|
|
{
|
|
if (!Session.IsAllowed(RoleConstants.MERGE_KOT))
|
|
return 0;
|
|
using (var bi = new VoucherBI())
|
|
return bi.MergeKot(kot.KotID, table);
|
|
}
|
|
private int MoveTable(FoodTable table)
|
|
{
|
|
if (!Session.IsAllowed(RoleConstants.MOVE_TABLE))
|
|
return 0;
|
|
using (var ft = new FoodTableBI())
|
|
return ft.Move(_billInfo.TableID, table);
|
|
}
|
|
private int MergeTable(FoodTable table)
|
|
{
|
|
if (!Session.IsAllowed(RoleConstants.MERGE_TABLE))
|
|
return 0;
|
|
int voucherID;
|
|
using (var bi = new VoucherBI())
|
|
voucherID = bi.MergeTables(_billInfo.VoucherID, table);
|
|
using (var bi = new VoucherBI())
|
|
bi.Delete(_billInfo.VoucherID);
|
|
return voucherID;
|
|
|
|
}
|
|
#endregion
|
|
#region Save
|
|
public void SaveKot()
|
|
{
|
|
#region Check if Allowed
|
|
if (!Session.IsAllowed(RoleConstants.PRINT_KOT))
|
|
return;
|
|
if (_billInfo.VoucherID != 0 && IsPrintedOrVoid(_billInfo))
|
|
return;
|
|
if (_bill.Count == 1) //new kot only
|
|
return;
|
|
#endregion
|
|
|
|
//Save
|
|
var saved = _billInfo.VoucherID == 0 ? InsertVoucher(false, !_editVoucherID.HasValue) : UpdateVoucher(false, !_editVoucherID.HasValue);
|
|
|
|
//Print
|
|
if ((!_editVoucherID.HasValue || _print) && saved.HasValue)
|
|
Thermal.PrintKot(_billInfo.VoucherID, saved.Value);
|
|
|
|
//Cleanup
|
|
if (_editVoucherID.HasValue)
|
|
_saleForm.CloseWindow();
|
|
else
|
|
ClearBill();
|
|
}
|
|
public void SaveBill()
|
|
{
|
|
#region Check if Allowed
|
|
if (!Session.IsAllowed(RoleConstants.PRINT_BILL))
|
|
return;
|
|
if (_bill.Count == 1) //new kot only
|
|
return;
|
|
#endregion
|
|
|
|
decimal amount;
|
|
|
|
var isReprint = IsReprint(out amount);
|
|
if (!isReprint.HasValue)
|
|
return;
|
|
else if (isReprint.Value)
|
|
{
|
|
SetDiscount();
|
|
SaveReprintOrDiscountBill(amount);
|
|
}
|
|
else
|
|
{
|
|
SetDiscount();
|
|
// Ask for VoucherType only for new bill, if none, then cancel
|
|
VoucherType? voucherType;
|
|
using (var frm = new VoucherTypeForm())
|
|
{
|
|
frm.ShowDialog();
|
|
voucherType = frm.Selection;
|
|
}
|
|
if (!voucherType.HasValue)
|
|
return;
|
|
_billInfo.VoucherType = voucherType.Value;
|
|
var saved = _billInfo.VoucherID == 0 ? InsertVoucher(true, !_editVoucherID.HasValue) : UpdateVoucher(true, !_editVoucherID.HasValue);
|
|
}
|
|
if (!_editVoucherID.HasValue || _print)
|
|
Thermal.PrintBill(_billInfo.VoucherID);
|
|
if (_editVoucherID.HasValue)
|
|
_saleForm.CloseWindow();
|
|
ClearBill();
|
|
}
|
|
public void SplitBill()
|
|
{
|
|
#region Permissions
|
|
|
|
bool isPrinted, isVoid;
|
|
IsPrintedOrVoid(_billInfo, out isPrinted, out isVoid);
|
|
if (_billInfo.VoucherID == 0 || isVoid)
|
|
return; // must be existing non void bill
|
|
|
|
if (!Session.IsAllowed(RoleConstants.SPLIT_BILL))
|
|
return;
|
|
#endregion
|
|
|
|
#region Get Move List
|
|
HashSet<string> splitList = null;
|
|
using (var bi = new ProductGroupBI())
|
|
{
|
|
using (var frm = new DiscountForm(bi.GetProductGroupTypes()))
|
|
if (frm.ShowDialog() == DialogResult.OK)
|
|
frm.Selection(out splitList);
|
|
}
|
|
if (splitList == null || splitList.Count == 0)
|
|
return;
|
|
|
|
var listFirst = _bill.Where(x => x.Key.BillItemType == BillItemType.Product && x.Key.KotID != 0 && splitList.Contains(x.Value.Product.ProductGroup.GroupType));
|
|
var listSecond = _bill.Where(x => x.Key.BillItemType == BillItemType.Product && x.Key.KotID != 0 && !splitList.Contains(x.Value.Product.ProductGroup.GroupType));
|
|
|
|
if (listFirst.Count() == 0 || listSecond.Count() == 0)
|
|
return; // all or none items selected to be moved
|
|
#endregion
|
|
|
|
var table = GetTableForMove(false);
|
|
if (table == null)
|
|
return;
|
|
|
|
#region new voucherFirst
|
|
var voucherFirst = new Voucher(Session.User)
|
|
{
|
|
Customer = _billInfo.Customer,
|
|
TableID = table.Name,
|
|
Waiter = _billInfo.Waiter,
|
|
Printed = isPrinted,
|
|
Void = false,
|
|
Narration = "",
|
|
VoucherType = _billInfo.VoucherType
|
|
};
|
|
|
|
var kotFirst = GetKot(listFirst);
|
|
if (kotFirst != null)
|
|
voucherFirst.Kots.Add(kotFirst);
|
|
#endregion
|
|
|
|
#region new voucherFirst
|
|
var voucherSecond = new Voucher(Session.User)
|
|
{
|
|
Customer = _billInfo.Customer,
|
|
TableID = _billInfo.TableID,
|
|
Waiter = _billInfo.Waiter,
|
|
Printed = isPrinted,
|
|
Void = false,
|
|
Narration = "",
|
|
VoucherType = _billInfo.VoucherType
|
|
};
|
|
|
|
var kotSecond = GetKot(listSecond);
|
|
if (kotSecond != null)
|
|
voucherSecond.Kots.Add(kotSecond);
|
|
#endregion
|
|
|
|
#region Old Voucher
|
|
_billInfo.User = Session.User;
|
|
_billInfo.Void = true;
|
|
_billInfo.VoidReason = "Bill Split";
|
|
#endregion
|
|
using (var session = SessionManager.Session)
|
|
{
|
|
var trans = session.BeginTransaction();
|
|
using (var bi = new VoucherBI(session, false))
|
|
bi.Insert(voucherFirst);
|
|
trans.Commit();
|
|
trans = session.BeginTransaction();
|
|
using (var bi = new VoucherBI(session, false))
|
|
bi.Insert(voucherSecond);
|
|
trans.Commit();
|
|
trans = session.BeginTransaction();
|
|
using (var bi = new VoucherBI(session, false))
|
|
bi.Update(_billInfo);
|
|
trans.Commit();
|
|
trans = session.BeginTransaction();
|
|
using (var ft = new FoodTableBI(session, false))
|
|
ft.UpdateStatus(voucherFirst);
|
|
using (var ft = new FoodTableBI(session, false))
|
|
ft.UpdateStatus(voucherSecond);
|
|
trans.Commit();
|
|
trans.Dispose();
|
|
}
|
|
if (isPrinted)
|
|
{
|
|
Thermal.PrintBill(voucherFirst.VoucherID);
|
|
Thermal.PrintBill(voucherSecond.VoucherID);
|
|
}
|
|
LoadBill(voucherFirst.VoucherID);
|
|
}
|
|
public void VoidBill()
|
|
{
|
|
#region Check conditions and Permissions
|
|
if (_billInfo.VoucherID == 0)
|
|
return;
|
|
//if (!_billInfo.Printed)
|
|
// return;
|
|
if (_billInfo.Void)
|
|
return;
|
|
if (!Session.IsAllowed(RoleConstants.VOID_BILL))
|
|
return;
|
|
if (MessageBox.Show("Are you sure you want to void this bill?", "Void Bill", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) != DialogResult.Yes)
|
|
return;
|
|
#endregion
|
|
|
|
var voidReason = new SelectVoidReason(GetVoidReason, true);
|
|
voidReason.ShowDialog();
|
|
if (voidReason.SelectedItem != null)
|
|
{
|
|
using (var session = SessionManager.Session)
|
|
{
|
|
using (var trans = session.BeginTransaction())
|
|
{
|
|
using (var bi = new VoucherBI(session, false))
|
|
bi.VoidBill(_billInfo.VoucherID, voidReason.SelectedItem.Description);
|
|
_billInfo.Void = true;
|
|
_billInfo.VoidReason = voidReason.SelectedItem.Description;
|
|
using (var ft = new FoodTableBI(session, false))
|
|
ft.UpdateStatus(_billInfo);
|
|
trans.Commit();
|
|
}
|
|
}
|
|
ClearBill();
|
|
}
|
|
else
|
|
{
|
|
MessageBox.Show("Please Select a reason if you want to void the bill", "Bill NOT Voided", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
|
|
}
|
|
}
|
|
|
|
private static List<StringType> GetVoidReason(Dictionary<string, string> filter)
|
|
{
|
|
var list = new List<StringType>
|
|
{
|
|
new StringType("Discount"),
|
|
new StringType("Printing Fault"),
|
|
new StringType("Item Changed"),
|
|
new StringType("Quantity Reduced"),
|
|
new StringType("Costing Bill for Party"),
|
|
new StringType("Cashier Mistake"),
|
|
new StringType("Management Freesale"),
|
|
new StringType("Other")
|
|
};
|
|
return list.Where(i => i.Description.ToLower().Contains(filter["Name"].ToLower().Trim())).ToList();
|
|
}
|
|
private void SaveReprintOrDiscountBill(decimal oldAmount)
|
|
{
|
|
var amountChanged = oldAmount != _bill.Where(x => x.Key.BillItemType == BillItemType.Product && x.Key.KotID != 0).Sum(x => x.Value.GrossAmount);
|
|
var itemsChanged = _bill.Where(x => x.Key.BillItemType == BillItemType.Product && x.Key.KotID == 0).Count() != 0;
|
|
if (amountChanged || itemsChanged) // Discount or Products changed
|
|
{
|
|
#region new voucherFirst
|
|
var voucherNew = new Voucher(Session.User)
|
|
{
|
|
Customer = _billInfo.Customer,
|
|
TableID = _billInfo.TableID,
|
|
Waiter = _billInfo.Waiter,
|
|
Printed = true,
|
|
Void = false,
|
|
Narration = "",
|
|
VoucherType = _billInfo.VoucherType
|
|
};
|
|
|
|
var kotNew = GetKot(_bill.Where(x => x.Key.BillItemType == BillItemType.Product));
|
|
if (kotNew != null)
|
|
voucherNew.Kots.Add(kotNew);
|
|
#endregion
|
|
|
|
#region Old Voucher
|
|
_billInfo.User = Session.User;
|
|
_billInfo.Void = true;
|
|
|
|
#endregion
|
|
using (var session = SessionManager.Session)
|
|
{
|
|
using (var trans = session.BeginTransaction())
|
|
{
|
|
using (var bi = new VoucherBI(session, false))
|
|
{
|
|
bi.Insert(voucherNew);
|
|
_billInfo.VoidReason = string.Format("Bill Discounted / Changed. New Bill ID is {0}", voucherNew.BillID);
|
|
bi.Update(_billInfo);
|
|
}
|
|
using (var ft = new FoodTableBI(session, false))
|
|
ft.UpdateStatus(voucherNew);
|
|
|
|
trans.Commit();
|
|
}
|
|
}
|
|
LoadBill(voucherNew.VoucherID);
|
|
}
|
|
else
|
|
{
|
|
using (var bi = new ReprintBI())
|
|
bi.Insert(new Reprint() { Date = DbValues.Date, User = Session.User, Voucher = _billInfo });
|
|
}
|
|
}
|
|
private int? InsertVoucher(bool finalBill, bool updateTable)
|
|
{
|
|
_billInfo.Printed = finalBill;
|
|
_billInfo.Void = false;
|
|
_billInfo.Narration = "";
|
|
//UpdateKots();
|
|
var kot = GetKot(_bill.Where(x => x.Key.BillItemType == BillItemType.Product && x.Key.KotID == 0 && x.Value.Quantity != 0));
|
|
if (kot == null)
|
|
return null;
|
|
_billInfo.Kots.Add(kot);
|
|
using (var session = SessionManager.Session)
|
|
{
|
|
using (var trans = session.BeginTransaction())
|
|
{
|
|
int? kotID;
|
|
using (var bi = new VoucherBI(session, false))
|
|
kotID = bi.Insert(_billInfo);
|
|
if (updateTable)
|
|
using (var ft = new FoodTableBI(session, false))
|
|
ft.UpdateStatus(_billInfo);
|
|
trans.Commit();
|
|
return kotID;
|
|
}
|
|
}
|
|
}
|
|
private int? UpdateVoucher(bool finalBill, bool updateTable)
|
|
{
|
|
_billInfo.User = Session.User;
|
|
|
|
UpdateKots();
|
|
if (!_billInfo.Printed)
|
|
{
|
|
var kot = GetKot(_bill.Where(x => x.Key.BillItemType == BillItemType.Product && x.Key.KotID == 0 && x.Value.Quantity != 0));
|
|
if (kot != null)
|
|
_billInfo.Kots.Add(kot);
|
|
}
|
|
|
|
_billInfo.Printed = finalBill;
|
|
|
|
using (var session = SessionManager.Session)
|
|
{
|
|
using (var trans = session.BeginTransaction())
|
|
{
|
|
int? kotID;
|
|
using (var bi = new VoucherBI(session, false))
|
|
kotID = bi.Update(_billInfo);
|
|
if (updateTable)
|
|
using (var ft = new FoodTableBI(session, false))
|
|
ft.UpdateStatus(_billInfo);
|
|
trans.Commit();
|
|
return kotID;
|
|
}
|
|
}
|
|
}
|
|
private void UpdateKots()
|
|
{
|
|
foreach (var item in _bill.Where(x => x.Key.BillItemType == BillItemType.Product && x.Key.KotID != 0))
|
|
{
|
|
var i = _billInfo.Kots.Single(x => x.KotID == item.Key.KotID).Inventories.Single(x => x.Product.ProductID == item.Key.ProductID);
|
|
i.Discount = item.Value.Discount;
|
|
i.Price = item.Value.Price;
|
|
}
|
|
}
|
|
private static Kot GetKot(IEnumerable<KeyValuePair<BillItemKey, BillItemValue>> list)
|
|
{
|
|
var kot = new Kot();
|
|
foreach (var item in list)
|
|
{
|
|
var oldInv = kot.Inventories.SingleOrDefault(x => x.Product.ProductID == item.Key.ProductID);
|
|
if (oldInv != null)
|
|
{
|
|
oldInv.Quantity += item.Value.Quantity;
|
|
if (oldInv.Quantity == 0)
|
|
kot.Inventories.Remove(oldInv);
|
|
}
|
|
else
|
|
{
|
|
var inv = new Inventory
|
|
{
|
|
Product = item.Value.Product,
|
|
Quantity = item.Value.Quantity,
|
|
Price = item.Value.Price,
|
|
FullPrice = item.Value.FullPrice,
|
|
Discount = item.Value.Discount,
|
|
ServiceCharge = item.Value.ServiceCharge,
|
|
IsScTaxable = item.Value.IsScTaxable,
|
|
ServiceTax = item.Value.ServiceTax,
|
|
Vat = item.Value.Vat
|
|
};
|
|
foreach (var mod in item.Value.Modifiers)
|
|
inv.InventoryModifier.Add(new InventoryModifier { Modifier = mod });
|
|
kot.Inventories.Add(inv);
|
|
}
|
|
}
|
|
|
|
return kot.Inventories.Count == 0 ? null : kot;
|
|
}
|
|
#endregion
|
|
|
|
#region InputBox
|
|
private bool GetInput(string prompt, ref decimal amount)
|
|
{
|
|
var result = InputBox.Show(prompt, amount.ToString(), InputBox_Validating);
|
|
if (!result.OK)
|
|
return false;
|
|
return decimal.TryParse(result.Text, out amount);
|
|
}
|
|
private bool GetInput(string prompt, ref string info)
|
|
{
|
|
var result = InputBox.Show(prompt, info, InputBox_Validating);
|
|
if (!result.OK)
|
|
return false;
|
|
info = result.Text.Trim();
|
|
return !string.IsNullOrEmpty(info);
|
|
}
|
|
#endregion
|
|
}
|
|
} |