diff --git a/Tanshu.Accounts.PointOfSale/Management/ManagementForm.cs b/Tanshu.Accounts.PointOfSale/Management/ManagementForm.cs index 3f5251a..5857de1 100644 --- a/Tanshu.Accounts.PointOfSale/Management/ManagementForm.cs +++ b/Tanshu.Accounts.PointOfSale/Management/ManagementForm.cs @@ -85,20 +85,6 @@ namespace Tanshu.Accounts.Management bwGo.ReportProgress(++count, "Starting on " + startDate.ToShortDateString() + " to " + finishDate.ToShortDateString()); using (var bi = new ManagementBI()) { - bi.DeleteVoid(sDate, fDate); - bwGo.ReportProgress(++count, "Voids Deleted"); - if (bwGo.CancellationPending == true) - { - e.Cancel = true; - return; - } - bi.MoveStaffToNc(sDate, fDate); - bwGo.ReportProgress(++count, "Staff Moved"); - if (bwGo.CancellationPending == true) - { - e.Cancel = true; - return; - } bi.ClearModifiers(sDate, fDate); bwGo.ReportProgress(++count, "Modifiers Cleared"); if (bwGo.CancellationPending == true) @@ -106,6 +92,27 @@ namespace Tanshu.Accounts.Management e.Cancel = true; return; } + bi.DeleteTobacco(sDate, fDate); + bwGo.ReportProgress(++count, "Tobacco Deleted"); + if (bwGo.CancellationPending == true) + { + e.Cancel = true; + return; + } + bi.DeleteReprints(sDate, fDate); + bwGo.ReportProgress(++count, "Reprints Deleted"); + if (bwGo.CancellationPending == true) + { + e.Cancel = true; + return; + } + bi.DeleteVoid(sDate, fDate); + bwGo.ReportProgress(++count, "Voids Deleted"); + if (bwGo.CancellationPending == true) + { + e.Cancel = true; + return; + } bi.CombineKots(sDate, fDate); bwGo.ReportProgress(++count, "Kots Combined"); if (bwGo.CancellationPending == true) @@ -120,6 +127,13 @@ namespace Tanshu.Accounts.Management e.Cancel = true; return; } + bi.MoveStaffToNc(sDate, fDate); + bwGo.ReportProgress(++count, "Staff Moved"); + if (bwGo.CancellationPending == true) + { + e.Cancel = true; + return; + } bwGo.ReportProgress(++count, "Starting beer"); foreach (var beerDate in beer) { @@ -140,12 +154,15 @@ namespace Tanshu.Accounts.Management e.Cancel = true; return; } - bi.MoveToNc(sDate, fDate, item.Sale.Where(x => x.IsLiq).Sum(x => x.Amount) / .75M); // Do not put all in NC this will allow for about 25% discount on the rest of non nc liqour - bwGo.ReportProgress(++count, "Moved to Nc"); - if (bwGo.CancellationPending == true) + foreach (var saleItem in item.Sale.Where(x => x.IsLiq)) { - e.Cancel = true; - return; + bi.LiqNcSwap(saleItem.Rate, saleItem.Amount, sDate, fDate); + bwGo.ReportProgress(++count, "Liq NC Swap " + saleItem.Rate.ToString()); + if (bwGo.CancellationPending == true) + { + e.Cancel = true; + return; + } } IList creditJ = credit.Where(x => x.Date >= startDate && x.Date <= finishDate).ToList(); bi.SetQuantityAndDiscount(item.Sale, creditJ, startDate, finishDate); diff --git a/Tanshu.Accounts.Repository/ManagementBI.cs b/Tanshu.Accounts.Repository/ManagementBI.cs index 47968f3..c5bd3da 100644 --- a/Tanshu.Accounts.Repository/ManagementBI.cs +++ b/Tanshu.Accounts.Repository/ManagementBI.cs @@ -128,40 +128,20 @@ namespace Tanshu.Accounts.Repository } public class ManagementBI : IUnitOfWork { - protected readonly ISession _session; + protected readonly IStatelessSession _session; private ITransaction _transaction; public ManagementBI() { - _session = SessionManager.Session; + _session = SessionManager.StatelessSession; _transaction = _session.BeginTransaction(); } #region Cleanup public void DeleteVoid(DateTime startDate, DateTime finishDate) { - var query = @"delete from Reprint r where r.Voucher in ( + var query = @"delete from VoucherSettlement vs where vs.Voucher in ( select v from Voucher v where v.Date >= :startDate and v.Date <= :finishDate and v.Void = :void )"; - _session - .CreateQuery(query) - .SetParameter("startDate", startDate) - .SetParameter("finishDate", finishDate) - .SetParameter("void", true) - .ExecuteUpdate(); - query = @"delete from VoucherSettlement vs where vs.Voucher in ( -select v from Voucher v where v.Date >= :startDate and v.Date <= :finishDate and v.Void = :void -)"; - _session - .CreateQuery(query) - .SetParameter("startDate", startDate) - .SetParameter("finishDate", finishDate) - .SetParameter("void", true) - .ExecuteUpdate(); - query = @"delete from InventoryModifier im where im.Inventory in ( -select i from Inventory i where i.Kot in ( -select k from Kot k where k.Voucher in ( -select v from Voucher v where v.Date >= :startDate and v.Date <= :finishDate and v.Void = :void -)))"; _session .CreateQuery(query) .SetParameter("startDate", startDate) @@ -195,6 +175,36 @@ select v from Voucher v where v.Date >= :startDate and v.Date <= :finishDate and .SetParameter("void", true) .ExecuteUpdate(); } + public void DeleteTobacco(DateTime startDate, DateTime finishDate) + { + const string query = @" +delete from Inventory i where i.Product in ( + select p from Product p where p.ProductGroup in ( + select pg from ProductGroup pg where pg.GroupType = :tobacco + ) +) and i.Kot in ( + select k from Kot k where k.Voucher in ( + select v from Voucher v where v.Date >= :startDate and v.Date <= :finishDate + ) +)"; + _session + .CreateQuery(query) + .SetParameter("startDate", startDate) + .SetParameter("finishDate", finishDate) + .SetParameter("tobacco", "Cash Charges") + .ExecuteUpdate(); + } + public void DeleteReprints(DateTime startDate, DateTime finishDate) + { + const string query = @"delete from Reprint r where r.Voucher in ( +select v from Voucher v where v.Date >= :startDate and v.Date <= :finishDate +)"; + _session + .CreateQuery(query) + .SetParameter("startDate", startDate) + .SetParameter("finishDate", finishDate) + .ExecuteUpdate(); + } public void MoveStaffToNc(DateTime startDate, DateTime finishDate) { var query = @"update Voucher set VoucherType = :nc where VoucherType = :staff and Date >= :startDate and Date <= :finishDate"; @@ -222,7 +232,7 @@ select v from Voucher v where v.Date >= :startDate and v.Date <= :finishDate public void CombineKots(DateTime startDate, DateTime finishDate) { var query = @" -select v.VoucherID, k.KotID, i.InventoryID, i.Product.ProductID, i.Quantity +select v.VoucherID, k.KotID, i.InventoryID, i.Product.ProductID, i.Quantity, i.IsHappyHour from Voucher v inner join v.Kots k inner join k.Inventories i @@ -241,23 +251,25 @@ order by v.Date, k.Date"; var inventoryID = (Guid)item[2]; var productID = (Guid)item[3]; var quantity = (decimal)item[4]; + var isHappyHour = (bool)item[5]; if (!vouchers.ContainsKey(voucherID)) vouchers.Add(voucherID, new Dictionary>()); if (!vouchers[voucherID].ContainsKey(kotID)) vouchers[voucherID].Add(kotID, new List()); - vouchers[voucherID][kotID].Add(new object[] { inventoryID, productID, quantity }); + vouchers[voucherID][kotID].Add(new object[] { inventoryID, productID, quantity, isHappyHour }); } foreach (var voucher in vouchers) { var kots = voucher.Value; if (kots.Count <= 1) continue; - Dictionary kotInventories = new Dictionary(); + Dictionary kotInventories = new Dictionary(); foreach (var item in kots.ElementAt(0).Value) { Guid inventoryID = (Guid)item[0]; Guid productID = (Guid)item[1]; - kotInventories.Add(productID, inventoryID); + bool isHappyHour = (bool)item[3]; + kotInventories.Add(productID.GetHashCode() ^ isHappyHour.GetHashCode(), inventoryID); } for (var i = kots.Count; i > 1; i--) { @@ -266,16 +278,18 @@ order by v.Date, k.Date"; Guid inventoryID = (Guid)item[0]; Guid productID = (Guid)item[1]; decimal quantity = (decimal)item[2]; - if (kotInventories.ContainsKey(productID)) + bool isHappyHour = (bool)item[3]; + var key = productID.GetHashCode() ^ isHappyHour.GetHashCode(); + if (kotInventories.ContainsKey(key)) { query = @"update Inventory set Quantity = Quantity + :quantity where InventoryID = :inventoryID"; - _session.CreateQuery(query).SetParameter("quantity", quantity).SetParameter("inventoryID", kotInventories[productID]).ExecuteUpdate(); + _session.CreateQuery(query).SetParameter("quantity", quantity).SetParameter("inventoryID", kotInventories[key]).ExecuteUpdate(); query = @"delete from Inventory where InventoryID = :inventoryID"; _session.CreateQuery(query).SetParameter("inventoryID", inventoryID).ExecuteUpdate(); } else { - kotInventories.Add(productID, inventoryID); + kotInventories.Add(key, inventoryID); query = @"update Inventory set Kot.KotID = :kotID where InventoryID = :inventoryID"; _session.CreateQuery(query).SetParameter("kotID", kots.ElementAt(0).Key).SetParameter("inventoryID", inventoryID).ExecuteUpdate(); } @@ -296,12 +310,6 @@ and k not in (select distinct i.Kot from Inventory i)"; .SetParameter("finishDate", finishDate) .ExecuteUpdate(); query = @"delete from VoucherSettlement vs where vs.Voucher in (select v from Voucher v where v.Date >= :startDate and v.Date <= :finishDate and v not in (select distinct k.Voucher from Kot k))"; - _session - .CreateQuery(query) - .SetParameter("startDate", startDate) - .SetParameter("finishDate", finishDate) - .ExecuteUpdate(); - query = @"delete from Reprint r where r.Voucher in (select v from Voucher v where v.Date >= :startDate and v.Date <= :finishDate and v not in (select distinct k.Voucher from Kot k))"; _session .CreateQuery(query) .SetParameter("startDate", startDate) @@ -314,6 +322,7 @@ and k not in (select distinct i.Kot from Inventory i)"; .SetParameter("finishDate", finishDate) .ExecuteUpdate(); } + public void SetPayments(DateTime startDate, DateTime finishDate) { var query = @"select v.VoucherID, v.VoucherType, sum(i.Amount) @@ -372,13 +381,11 @@ where vs.Voucher.VoucherID = :voucherID and ( .CreateQuery(query) .SetParameter("voucherID", item.Key) .ExecuteUpdate(); - _session.Save(new VoucherSettlement() { Voucher = new Voucher() { VoucherID = item.Key }, Amount = amount, Settled = SettleOption.Amount }); - _session.Save(new VoucherSettlement() { Voucher = new Voucher() { VoucherID = item.Key }, Amount = roundoff, Settled = SettleOption.RoundOff }); - _session.Save(new VoucherSettlement() { Voucher = new Voucher() { VoucherID = item.Key }, Amount = -1 * (amount + roundoff), Settled = settlementType }); + _session.Insert(new VoucherSettlement() { Voucher = new Voucher() { VoucherID = item.Key }, Amount = amount, Settled = SettleOption.Amount }); + _session.Insert(new VoucherSettlement() { Voucher = new Voucher() { VoucherID = item.Key }, Amount = roundoff, Settled = SettleOption.RoundOff }); + _session.Insert(new VoucherSettlement() { Voucher = new Voucher() { VoucherID = item.Key }, Amount = -1 * (amount + roundoff), Settled = settlementType }); } } - - public void UpdateBillID(DateTime startDate, DateTime finishDate) { var query = @" @@ -453,16 +460,29 @@ order by v.Date desc } #endregion - public void MoveToNc(DateTime startDate, DateTime finishDate, decimal target) + public void LiqNcSwap(decimal rate, decimal target, DateTime startDate, DateTime finishDate) + { + var existingSale = GetSaleAmount(rate, startDate, finishDate); + if (existingSale > target / .75M) + { + // Do not put all in NC this will allow for about 25% discount on the rest of non nc liqour + existingSale = MoveToNc(rate, target / .75M, startDate, finishDate); + } + else if (existingSale < target) + { + existingSale = MoveFromNc(rate, target, startDate, finishDate); + } + } + public decimal MoveToNc(decimal rate, decimal target, DateTime startDate, DateTime finishDate) { string query = @" -select v.VoucherID, sum(i.Amount) +select v.VoucherID, sum(i.Quantity * i.Price * (1 - i.Discount) * (1 + case when i.IsScTaxable then i.ServiceCharge else 0 end)) from Voucher v inner join v.Kots k inner join k.Inventories i -where v.Date >= :startDate and v.Date <= :finishDate and i.Vat.TaxID = :vatLiquor and v.Void = false and v.VoucherType not in (:nc, :staff) +where v.Date >= :startDate and v.Date <= :finishDate and i.Vat.TaxID = :vatLiquor and i.VatRate = :vatRate and v.Void = false and v.VoucherType not in (:nc, :staff) group by v.VoucherID -order by sum(i.Amount) desc +order by sum(i.Quantity * i.Price * (1 - i.Discount) * (1 + case when i.IsScTaxable then i.ServiceCharge else 0 end)) desc "; var list = _session .CreateQuery(query) @@ -471,8 +491,9 @@ order by sum(i.Amount) desc .SetParameter("nc", VoucherType.NoCharge) .SetParameter("staff", VoucherType.Staff) .SetParameter("vatLiquor", new Guid("2C8AD8EC-E09A-4194-B348-01243474CF26")) + .SetParameter("vatRate", rate) .List(); - var totalAmount = GetSaleAmount(.1575M, startDate, finishDate) + GetSaleAmount(.2625M, startDate, finishDate); + var totalAmount = GetSaleAmount(rate, startDate, finishDate); for (int i = 0; i < list.Count / 20; i += 2) // Skip every alternate bill { if (totalAmount <= target) @@ -489,6 +510,45 @@ order by sum(i.Amount) desc .ExecuteUpdate(); totalAmount -= amount; } + return totalAmount; + } + public decimal MoveFromNc(decimal rate, decimal target, DateTime startDate, DateTime finishDate) + { + string query = @" +select v.VoucherID, sum(i.Quantity * i.Price * (1 - i.Discount) * (1 + case when i.IsScTaxable then i.ServiceCharge else 0 end)) +from Voucher v +inner join v.Kots k +inner join k.Inventories i +where v.Date >= :startDate and v.Date <= :finishDate and i.Vat.TaxID = :vatLiquor and i.VatRate = :vatRate and v.Void = false and v.VoucherType = :nc +group by v.VoucherID +order by sum(i.Quantity * i.Price * (1 - i.Discount) * (1 + case when i.IsScTaxable then i.ServiceCharge else 0 end)) desc + "; + var list = _session + .CreateQuery(query) + .SetParameter("startDate", startDate) + .SetParameter("finishDate", finishDate) + .SetParameter("nc", VoucherType.NoCharge) + .SetParameter("vatLiquor", new Guid("2C8AD8EC-E09A-4194-B348-01243474CF26")) + .SetParameter("vatRate", rate) + .List(); + var existingSale = GetSaleAmount(rate, startDate, finishDate); + for (int i = 0; i < list.Count; i += 1) + { + if (existingSale >= target) + break; + var item = (object[])list[i]; + var voucherID = (Guid)item[0]; + var amount = (decimal)item[1]; + + query = @"update Voucher set VoucherType = :regular where VoucherID = :voucherID"; + _session + .CreateQuery(query) + .SetParameter("regular", VoucherType.Regular) + .SetParameter("voucherID", voucherID) + .ExecuteUpdate(); + existingSale += amount; + } + return existingSale; } public IList GetSaleAndVat(DateTime startDate, DateTime finishDate) { @@ -605,7 +665,7 @@ where v.Date >= :startDate and v.Date <= :finishDate and i.VatRate = :vat and v. { var list = new List(); const string query = @" - select i.VatRate, sum(i.Quantity * i.Price * (1 - i.Discount) * (1 + case when i.IsScTaxable then i.ServiceCharge else 0 end)), sum(i.Amount) + select i.VatRate, sum(i.Quantity * i.EffectivePrice * (1 - i.Discount) * (1 + case when i.IsScTaxable then i.ServiceCharge else 0 end)), sum(i.Amount) from Voucher v inner join v.Kots k inner join k.Inventories i @@ -629,36 +689,26 @@ where v.Date >= :startDate and v.Date <= :finishDate and i.VatRate = :vat and v. } return list; } - private class InvDate : Inventory + private class InvDate { public DateTime Date { get; set; } - public decimal Net - { - get - { - var effectivePrice = IsHappyHour ? 0 : Price; - if (IsScTaxable) - return Quantity * effectivePrice * (1 - Discount) * (1 + ServiceCharge); - return Quantity * effectivePrice * (1 - Discount); - } - } + public Inventory Inv { get; set; } } public void SetQuantityAndDiscount(IList sale, IList credit, DateTime startDate, DateTime finishDate) { var rand = new Random(); - var query = @" -select v.Date, i.InventoryID, i.Quantity, i.Price, i.Discount, i.ServiceCharge, i.IsScTaxable, i.ServiceTaxRate, i.VatRate + const string query = @" +select v.Date, i from Voucher v inner join v.Kots k inner join k.Inventories i where v.Date >= :startDate and v.Date <= :finishDate -and v.VoucherType in (:regular, :takeAway)"; +and v.VoucherType = :regular"; var list = _session .CreateQuery(query) .SetParameter("startDate", startDate.AddHours(7)) .SetParameter("finishDate", finishDate.AddDays(1).AddHours(7)) .SetParameter("regular", VoucherType.Regular) - .SetParameter("takeAway", VoucherType.TakeAway) .List(); List inventories = new List(); foreach (var item in Randomize(list)) @@ -666,98 +716,182 @@ and v.VoucherType in (:regular, :takeAway)"; inventories.Add(new InvDate() { Date = ((DateTime)item[0]).AddHours(-7).Date, - InventoryID = (Guid)item[1], - Quantity = (decimal)item[2], - Price = (decimal)item[3], - Discount = (decimal)item[4], - ServiceCharge = (decimal)item[5], - IsScTaxable = (bool)item[6], - ServiceTaxRate = (decimal)item[7], - VatRate = (decimal)item[8] + Inv = (Inventory)item[1] }); } - var sales = GetSaleAmount(startDate, finishDate); - List continueDates = new List(); - List continueVat = new List(); - var creditSale = credit.Sum(x => x.Amount); - //this is approx, but more than actual as the formula does not take into account service tax - var creditLiqSale = creditSale - sale.Where(x => x.IsLiq == false).Sum(x => x.Amount * (1 + x.Rate)); - var actualLiqSale = sales.Where(x => sale.Where(y => y.IsLiq == true).Select(y => y.Rate).Contains(x.VatRate)).Sum(x => x.Gross); - var max = 1 - (creditLiqSale / actualLiqSale); - max = Math.Min(.90M, Math.Round(max, 2) * 2); - max = Math.Max(.10M, max); - int run = 0; - - while (continueVat.Intersect(sale.Select(x => x.Rate)).Count() != continueVat.Union(sale.Select(x => x.Rate)).Count() && continueDates.Intersect(credit.Select(x => x.Date)).Count() != continueDates.Union(credit.Select(x => x.Date)).Count() && ++run <= 10) + var dailySaleGroupedByVat = GetSaleAmount(startDate, finishDate); + foreach (var s in sale) { - foreach (var inv in inventories) + // Now sale will contain the amounts to be adjusted + // +ve is the amount to reduce by, -ve is amount to increase sale by + var currentNetSale = dailySaleGroupedByVat.Where(x => x.VatRate == s.Rate).Sum(x => x.Net); + s.Amount = currentNetSale - s.Amount; + } + foreach (var c in credit) + { + // Now credit will contain the margin available for the day + c.Amount = dailySaleGroupedByVat.Where(x => x.Date == c.Date).Sum(x => x.Gross) - c.Amount; + } + foreach (var inv in inventories) + { + var s = sale.SingleOrDefault(x => x.Rate == inv.Inv.VatRate); + var c = credit.SingleOrDefault(x => x.Date == inv.Date); + if (s == null) + throw new ArgumentException("Unknown type of vat rate encountered"); + if (c == null) + throw new ArgumentException("Unknown date encountered"); + if (Math.Abs(s.Amount) < 10) + continue; // Close enough for now + if (s.Amount > 0 && c.Amount < 10) + continue; //Move on if we have to reduce and we do not have credit sale margin + if (!s.IsLiq) //Food { - if (sale.Count(x => x.Rate == inv.VatRate) == 0) - throw new ArgumentException("Unknown type of vat rate encountered"); - - var creditForDay = credit.SingleOrDefault(x => x.Date == inv.Date).Amount; - var grossSaleForDay = sales.Where(x => x.Date == inv.Date).Sum(x => x.Gross); - if (creditForDay >= grossSaleForDay && !continueDates.Contains(inv.Date)) - continueDates.Add(inv.Date); - var targetVatAmountForPeriod = sale.SingleOrDefault(x => x.Rate == inv.VatRate).Amount; - var vatRemainingForPeriod = sales.Where(x => x.VatRate == inv.VatRate).Sum(x => x.Net); - if (vatRemainingForPeriod <= targetVatAmountForPeriod && !continueVat.Contains(inv.VatRate)) - continueVat.Add(inv.VatRate); - - if (continueDates.Contains(inv.Date) || continueVat.Contains(inv.VatRate)) - continue; - - var vatLeft = vatRemainingForPeriod - targetVatAmountForPeriod; - var creditLeft = grossSaleForDay - creditForDay; - var left = Math.Min(vatLeft, creditLeft); //Net Gross conversion - - var isLiq = sale.SingleOrDefault(x => x.Rate == inv.VatRate).IsLiq; - if (isLiq) + if (inv.Inv.IsHappyHour) + throw new ArgumentException("Non-liqour does not have happy hour"); + if (s.Amount < 0) { - if (inv.Discount >= max || inv.Price == 0) - continue; - var minimum = inv.Discount == 0 ? 10 : Convert.ToInt32(inv.Discount * 100) + 1; - var discount = Convert.ToDecimal(rand.Next(minimum, Convert.ToInt32(max * 100))) / 100; - - if (inv.Net * (discount - inv.Discount) > left) - { - discount = Math.Round(left * (1 - inv.Discount) / inv.Net, 2); - } - query = @"update Inventory set Discount = :discount where InventoryID = :inventoryID"; - _session.CreateQuery(query).SetParameter("discount", discount).SetParameter("inventoryID", inv.InventoryID).ExecuteUpdate(); - // reduce from daily - var saleItem = sales.Single(x => x.Date == inv.Date && x.VatRate == inv.VatRate); - inv.Discount += 1 - discount; - saleItem.Net -= Math.Round(inv.Net); - saleItem.Gross -= Math.Round(inv.Amount); + IncreaseFood(s, inv, c); } else { - if (inv.Net > left) - { - var ratio = (inv.Net - left) / inv.Net; - query = @"update Inventory set Quantity = Quantity * :ratio where InventoryID = :inventoryID"; - _session.CreateQuery(query).SetParameter("ratio", ratio).SetParameter("inventoryID", inv.InventoryID).ExecuteUpdate(); - // reduce from daily - var saleItem = sales.Single(x => x.Date == inv.Date && x.VatRate == inv.VatRate); - inv.Quantity -= inv.Quantity * ratio; - saleItem.Net -= Math.Round(inv.Net); - saleItem.Gross -= Math.Round(inv.Amount); - } - else - { - query = @"delete from Inventory where InventoryID = :inventoryID"; - _session.CreateQuery(query).SetParameter("inventoryID", inv.InventoryID).ExecuteUpdate(); - // reduce from daily - var saleItem = sales.Single(x => x.Date == inv.Date && x.VatRate == inv.VatRate); - saleItem.Net -= inv.Net; - saleItem.Gross -= inv.Amount; - } + DecreaseFood(s, inv, c); + } + } + else + { + if (s.Amount < 0) + { + //Increase Sales + if (inv.Inv.IsHappyHour) + IncreaseLiqourUsingHappyHour(s, inv, c); + else if (inv.Inv.Discount > .10M) + IncreaseLiqourUsingDiscount(s, inv, c); + + } + else + { + DecreaseLiqour(rand, s, inv, c); } } } } + private void IncreaseFood(SaleDetailJson s, InvDate inv, CreditJson c) + { + //Increase Sales + if (inv.Inv.Discount != 0) + { + var invMax = inv.Inv.Quantity * inv.Inv.EffectivePrice; + decimal discount; + if (invMax * inv.Inv.Discount < -1 * s.Amount) + discount = 0; + else + discount = (s.Amount * -1) / invMax; + + const string query = @"update Inventory set Discount = :discount where InventoryID = :inventoryID"; + _session.CreateQuery(query).SetParameter("discount", discount).SetParameter("inventoryID", inv.Inv.InventoryID).ExecuteUpdate(); + s.Amount += invMax * (inv.Inv.Discount - discount); + c.Amount += inv.Inv.Amount * (inv.Inv.Discount - discount); + } + + } + private void DecreaseFood(SaleDetailJson s, InvDate inv, CreditJson c) + { + if (inv.Inv.Net > s.Amount || inv.Inv.Amount > c.Amount) + { + var netRatio = (inv.Inv.Net - s.Amount) / inv.Inv.Net; + var grossRatio = (inv.Inv.Amount - c.Amount) / inv.Inv.Amount; + decimal ratio; + if (netRatio < 0) + ratio = grossRatio; + else if (grossRatio < 0) + ratio = netRatio; + else + ratio = Math.Min(netRatio, grossRatio); + + + const string query = @"update Inventory set Quantity = Quantity * :ratio where InventoryID = :inventoryID"; + _session.CreateQuery(query).SetParameter("ratio", ratio).SetParameter("inventoryID", inv.Inv.InventoryID).ExecuteUpdate(); + // reduce from daily + s.Amount -= inv.Inv.Net * (1 - ratio); + c.Amount -= inv.Inv.Amount * (1 - ratio); + } + else + { + const string query = @"delete from Inventory where InventoryID = :inventoryID"; + _session.CreateQuery(query).SetParameter("inventoryID", inv.Inv.InventoryID).ExecuteUpdate(); + // reduce from daily + s.Amount -= inv.Inv.Net; + c.Amount -= inv.Inv.Amount; + } + } + private void IncreaseLiqourUsingHappyHour(SaleDetailJson s, InvDate inv, CreditJson c) + { + var query = @"select count(*) from Inventory i where i.Product.ProductID = :productID and i.IsHappyHour = :false and i.Kot.KotID = :kotID"; + var old = _session.CreateQuery(query) + .SetParameter("productID", inv.Inv.Product.ProductID) + .SetParameter("false", false) + .SetParameter("kotID", inv.Inv.Kot.KotID) + .UniqueResult(); + + if (old > 0) + { + query = @"update Inventory i set Quantity = Quantity + :quantity where i.Product.ProductID = :productID and i.IsHappyHour = :false and i.Kot.KotID = :kotID"; + _session.CreateQuery(query) + .SetParameter("quantity", inv.Inv.Quantity) + .SetParameter("productID", inv.Inv.Product.ProductID) + .SetParameter("false", false) + .SetParameter("kotID", inv.Inv.Kot.KotID) + .ExecuteUpdate(); + query = @"delete from Inventory where InventoryID = :inventoryID"; + _session.CreateQuery(query).SetParameter("inventoryID", inv.Inv.InventoryID).ExecuteUpdate(); + } + else + { + query = @"update Inventory set IsHappyHour = :false where InventoryID = :inventoryID"; + _session.CreateQuery(query).SetParameter("false", false).SetParameter("inventoryID", inv.Inv.InventoryID).ExecuteUpdate(); + } + inv.Inv.IsHappyHour = false; + s.Amount += inv.Inv.Net; + c.Amount += inv.Inv.Amount; + } + private void IncreaseLiqourUsingDiscount(SaleDetailJson s, InvDate inv, CreditJson c) + { + decimal discount; + if (s.Amount * -1 > inv.Inv.Quantity * inv.Inv.EffectivePrice * inv.Inv.Discount) + discount = 0; + else + discount = inv.Inv.Discount + Math.Round(s.Amount / (inv.Inv.Quantity * inv.Inv.EffectivePrice), 2); + + const string query = @"update Inventory i set Discount = :discount where i.InventoryID = :inventoryID"; + _session.CreateQuery(query) + .SetParameter("discount", discount) + .SetParameter("inventoryID", inv.Inv.InventoryID) + .ExecuteUpdate(); + inv.Inv.Discount = 1 - (inv.Inv.Discount - discount); + s.Amount += inv.Inv.Net; + c.Amount += inv.Inv.Amount; + } + private void DecreaseLiqour(Random r, SaleDetailJson s, InvDate inv, CreditJson c) + { + var min = Math.Max(Convert.ToInt32(inv.Inv.Discount * 100) + 1, 10); + var discount = Convert.ToDecimal(r.Next(min, 90)) / 100; + var netChange = inv.Inv.Quantity * inv.Inv.EffectivePrice * (discount - inv.Inv.Discount); + + if (netChange > s.Amount) + { + discount = s.Amount / (inv.Inv.Quantity * inv.Inv.EffectivePrice); + discount = Math.Round(discount, 2); + } + netChange = inv.Inv.Quantity * inv.Inv.EffectivePrice * (discount - inv.Inv.Discount); + + const string query = @"update Inventory set Discount = :discount where InventoryID = :inventoryID"; + _session.CreateQuery(query).SetParameter("discount", discount).SetParameter("inventoryID", inv.Inv.InventoryID).ExecuteUpdate(); + + var grossChange = inv.Inv.Amount * (discount - inv.Inv.Discount); + s.Amount -= netChange; + c.Amount -= grossChange; + } #region Beer public decimal GetBeer(DateTime startDate, DateTime finishDate)