Converted Session to Stateless Session in the ManagementBI as State Session
would randomly give a stale state error. Fixed numerous bugs in the ManagementBI. Needs testing, but should be working now.
This commit is contained in:
parent
57f3f7e08d
commit
5124347d1b
@ -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<CreditJson> creditJ = credit.Where(x => x.Date >= startDate && x.Date <= finishDate).ToList();
|
||||
bi.SetQuantityAndDiscount(item.Sale, creditJ, startDate, finishDate);
|
||||
|
@ -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<Guid, List<object[]>>());
|
||||
if (!vouchers[voucherID].ContainsKey(kotID))
|
||||
vouchers[voucherID].Add(kotID, new List<object[]>());
|
||||
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<Guid, Guid> kotInventories = new Dictionary<Guid, Guid>();
|
||||
Dictionary<Int32, Guid> kotInventories = new Dictionary<Int32, Guid>();
|
||||
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<SaleInfo> 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<DateVatSale>();
|
||||
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<SaleDetailJson> sale, IList<CreditJson> 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<object[]>();
|
||||
List<InvDate> inventories = new List<InvDate>();
|
||||
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<DateTime> continueDates = new List<DateTime>();
|
||||
List<decimal> continueVat = new List<decimal>();
|
||||
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<long>();
|
||||
|
||||
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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user