Feature: Added Machine Locations so that setting the location in the config file is not needed.
Feature: Settings database table added to store string based settings.
It is right now used to store bill header and footer.
Hard Coded header/footer removed from file.
Feature: Tax Analysis form created to easily show the tax calculation.
Feature: Management form uses background workers. Dont' know if it is functional though.
Chore: Reorder Table form moved to masters from sales folder.
Refactor: ManagementBI and SalesAnalysisBI
This commit is contained in:
@ -1,27 +1,72 @@
|
||||
using NHibernate;
|
||||
using Tanshu.Accounts.Entities;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using System.Configuration;
|
||||
using NHibernate;
|
||||
using Tanshu.Accounts.Entities;
|
||||
using Tanshu.Accounts.Entities.Auth;
|
||||
|
||||
namespace Tanshu.Accounts.Repository
|
||||
{
|
||||
public class Cache
|
||||
{
|
||||
private static IList<ProductGroup> cache = null;
|
||||
private static Dictionary<int, PrintLocation> locations = new Dictionary<int, PrintLocation>();
|
||||
private static Dictionary<Guid, IList<Modifier>> modifiers = new Dictionary<Guid, IList<Modifier>>();
|
||||
private static string location = ConfigurationManager.AppSettings["Location"].ToLowerInvariant();
|
||||
|
||||
private static IList<Role> roles = null;
|
||||
|
||||
private static IList<ProductGroup> _productGroups = null;
|
||||
private static Dictionary<Guid, IList<Modifier>> _modifiers = new Dictionary<Guid, IList<Modifier>>();
|
||||
private static string _machine = Environment.MachineName;
|
||||
private static string _location = null;
|
||||
private static Dictionary<int, PrintLocation> _locations = new Dictionary<int, PrintLocation>();
|
||||
private static IList<Role> _roles = null;
|
||||
private static bool _log = false;
|
||||
|
||||
public static string Location
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(_location))
|
||||
{
|
||||
using (var bi = new MachineLocationBI())
|
||||
{
|
||||
var loc = bi.Get(x => x.Machine == _machine);
|
||||
if (loc != null)
|
||||
_location = loc.Location;
|
||||
}
|
||||
}
|
||||
return _location;
|
||||
}
|
||||
}
|
||||
public static PrintLocation BasePrinter
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(Location))
|
||||
throw new ArgumentException("No location for Machine");
|
||||
if (!_locations.ContainsKey(Location.GetHashCode()))
|
||||
{
|
||||
using (var bi = new PrintLocationBI())
|
||||
{
|
||||
var loc = bi.Get(x => x.Location == Location && x.ProductGroup == null);
|
||||
_locations.Add(Location.GetHashCode(), loc);
|
||||
}
|
||||
}
|
||||
return _locations[Location.GetHashCode()];
|
||||
}
|
||||
}
|
||||
public static PrintLocation KotPrinter(Guid productGroupID)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Location))
|
||||
throw new ArgumentException("No location for Machine");
|
||||
if (!_locations.ContainsKey(Location.GetHashCode() ^ productGroupID.GetHashCode()))
|
||||
{
|
||||
using (var bi = new PrintLocationBI())
|
||||
{
|
||||
var loc = bi.Get(x => x.Location == Location && x.ProductGroup.ProductGroupID == productGroupID) ??
|
||||
bi.Get(x => x.Location == Location && x.ProductGroup == null);
|
||||
_locations.Add(Location.GetHashCode() ^ productGroupID.GetHashCode(), loc);
|
||||
}
|
||||
}
|
||||
return _locations[Location.GetHashCode() ^ productGroupID.GetHashCode()];
|
||||
}
|
||||
public static IList<ProductGroup> ProductGroups()
|
||||
{
|
||||
if (cache == null)
|
||||
if (_productGroups == null)
|
||||
{
|
||||
using (var bi = new ProductGroupBI())
|
||||
{
|
||||
@ -30,72 +75,46 @@ namespace Tanshu.Accounts.Repository
|
||||
{
|
||||
NHibernateUtil.Initialize(item.Products);
|
||||
}
|
||||
cache = list;
|
||||
_productGroups = list;
|
||||
}
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
public static PrintLocation BasePrinter
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!locations.ContainsKey(location.GetHashCode()))
|
||||
{
|
||||
using (var bi = new PrintLocationBI())
|
||||
{
|
||||
var loc = bi.Get(x => x.Location == location && x.ProductGroup == null);
|
||||
locations.Add(location.GetHashCode(), loc);
|
||||
}
|
||||
}
|
||||
return locations[location.GetHashCode()];
|
||||
}
|
||||
}
|
||||
public static PrintLocation KotPrinter(Guid productGroupID)
|
||||
{
|
||||
if (!locations.ContainsKey(location.GetHashCode() ^ productGroupID.GetHashCode()))
|
||||
{
|
||||
using (var bi = new PrintLocationBI())
|
||||
{
|
||||
var loc = bi.Get(x => x.Location == location && x.ProductGroup.ProductGroupID == productGroupID) ??
|
||||
bi.Get(x => x.Location == location && x.ProductGroup == null);
|
||||
locations.Add(location.GetHashCode() ^ productGroupID.GetHashCode(), loc);
|
||||
}
|
||||
}
|
||||
return locations[location.GetHashCode() ^ productGroupID.GetHashCode()];
|
||||
return _productGroups;
|
||||
}
|
||||
public static IList<Modifier> ProductGroupModifiers(Guid productGroupID)
|
||||
{
|
||||
if (!modifiers.ContainsKey(productGroupID))
|
||||
if (!_modifiers.ContainsKey(productGroupID))
|
||||
{
|
||||
using (var bi = new ProductGroupModifierBI())
|
||||
{
|
||||
var list = bi.List(productGroupID);
|
||||
modifiers.Add(productGroupID, list);
|
||||
_modifiers.Add(productGroupID, list);
|
||||
}
|
||||
}
|
||||
return modifiers[productGroupID];
|
||||
return _modifiers[productGroupID];
|
||||
}
|
||||
public static IList<Role> UserRoles(Guid userID)
|
||||
{
|
||||
if (roles == null)
|
||||
if (_roles == null)
|
||||
{
|
||||
using (var bi = new UserBI())
|
||||
{
|
||||
roles = bi.Roles(userID);
|
||||
_roles = bi.Roles(userID);
|
||||
}
|
||||
}
|
||||
return roles;
|
||||
}
|
||||
public static void ClearRoles()
|
||||
{
|
||||
roles = null;
|
||||
return _roles;
|
||||
}
|
||||
|
||||
public static void ClearRoles()
|
||||
{
|
||||
_roles = null;
|
||||
}
|
||||
public static void Invalidate()
|
||||
{
|
||||
cache = null;
|
||||
locations = new Dictionary<int, PrintLocation>();
|
||||
modifiers = new Dictionary<Guid, IList<Modifier>>();
|
||||
_productGroups = null;
|
||||
_machine = Environment.MachineName;
|
||||
_location = null;
|
||||
_locations = new Dictionary<int, PrintLocation>();
|
||||
_modifiers = new Dictionary<Guid, IList<Modifier>>();
|
||||
}
|
||||
public static bool Log
|
||||
{
|
||||
|
||||
17
Tanshu.Accounts.Repository/MachineLocationBI.cs
Normal file
17
Tanshu.Accounts.Repository/MachineLocationBI.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using NHibernate;
|
||||
using Tanshu.Accounts.Entities;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace Tanshu.Accounts.Repository
|
||||
{
|
||||
public class MachineLocationBI : UnitOfWork<MachineLocation>
|
||||
{
|
||||
public IList<string> LocationList()
|
||||
{
|
||||
const string query = @"select distinct(pl.Location) from PrintLocation pl order by pl.Location";
|
||||
var hnq = _session.CreateQuery(query);
|
||||
return hnq.List<string>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -29,35 +29,35 @@ namespace Tanshu.Accounts.Repository
|
||||
IFormatProvider culture = new CultureInfo("en-US", true);
|
||||
private DateTime? dateStart;
|
||||
private DateTime? dateFinish;
|
||||
public string StartDate { get; set; }
|
||||
public string FinishDate { get; set; }
|
||||
public string _startDate { get; set; }
|
||||
public string _finishDate { get; set; }
|
||||
public IList<SaleDetailJson> Sale { get; set; }
|
||||
public DateTime? SDate
|
||||
public DateTime StartDate
|
||||
{
|
||||
get
|
||||
{
|
||||
if (dateStart.HasValue)
|
||||
return dateStart;
|
||||
DateTime dStart;
|
||||
if (!DateTime.TryParseExact(StartDate, "dd-MM-yyyy", culture, DateTimeStyles.NoCurrentDateDefault, out dStart))
|
||||
dateStart = null;
|
||||
else
|
||||
dateStart = dStart;
|
||||
return dateStart;
|
||||
if (!dateStart.HasValue)
|
||||
{
|
||||
DateTime tDate;
|
||||
if (!DateTime.TryParseExact(_startDate, "dd-MMM-yyyy", culture, DateTimeStyles.NoCurrentDateDefault, out tDate))
|
||||
throw new ArgumentException();
|
||||
dateStart = tDate;
|
||||
}
|
||||
return dateStart.Value;
|
||||
}
|
||||
}
|
||||
public DateTime? FDate
|
||||
public DateTime FinishDate
|
||||
{
|
||||
get
|
||||
{
|
||||
if (dateFinish.HasValue)
|
||||
return dateFinish;
|
||||
DateTime dFinish;
|
||||
if (!DateTime.TryParseExact(FinishDate, "dd-MM-yyyy", culture, DateTimeStyles.NoCurrentDateDefault, out dFinish))
|
||||
dateFinish = null;
|
||||
else
|
||||
dateFinish = dFinish;
|
||||
return dateFinish;
|
||||
if (!dateFinish.HasValue)
|
||||
{
|
||||
DateTime tDate;
|
||||
if (!DateTime.TryParseExact(_finishDate, "dd-MMM-yyyy", culture, DateTimeStyles.NoCurrentDateDefault, out tDate))
|
||||
throw new ArgumentException();
|
||||
dateFinish = tDate;
|
||||
}
|
||||
return dateFinish.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -71,20 +71,20 @@ namespace Tanshu.Accounts.Repository
|
||||
{
|
||||
IFormatProvider culture = new CultureInfo("en-US", true);
|
||||
private DateTime? date;
|
||||
public string Date { get; set; }
|
||||
public string _date { get; set; }
|
||||
public IList<BeerDetailJson> Beers { get; set; }
|
||||
public DateTime? bDate
|
||||
public DateTime Date
|
||||
{
|
||||
get
|
||||
{
|
||||
if (date.HasValue)
|
||||
return date;
|
||||
DateTime tDate;
|
||||
if (!DateTime.TryParseExact(Date, "d MMM yy", culture, DateTimeStyles.NoCurrentDateDefault, out tDate))
|
||||
date = null;
|
||||
else
|
||||
if (!date.HasValue)
|
||||
{
|
||||
DateTime tDate;
|
||||
if (!DateTime.TryParseExact(_date, "dd-MMM-yyyy", culture, DateTimeStyles.NoCurrentDateDefault, out tDate))
|
||||
throw new ArgumentException();
|
||||
date = tDate;
|
||||
return tDate;
|
||||
}
|
||||
return date.Value;
|
||||
}
|
||||
}
|
||||
public decimal Quantity
|
||||
@ -109,20 +109,20 @@ namespace Tanshu.Accounts.Repository
|
||||
{
|
||||
IFormatProvider culture = new CultureInfo("en-US", true);
|
||||
private DateTime? date;
|
||||
public string Date { get; set; }
|
||||
public string _date { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
public DateTime? CDate
|
||||
public DateTime Date
|
||||
{
|
||||
get
|
||||
{
|
||||
if (date.HasValue)
|
||||
return date;
|
||||
DateTime tDate;
|
||||
if (!DateTime.TryParseExact(Date, "dd/MM/yyyy", culture, DateTimeStyles.NoCurrentDateDefault, out tDate))
|
||||
date = null;
|
||||
else
|
||||
if (!date.HasValue)
|
||||
{
|
||||
DateTime tDate;
|
||||
if (!DateTime.TryParseExact(_date, "dd-MMM-yyyy", culture, DateTimeStyles.NoCurrentDateDefault, out tDate))
|
||||
throw new ArgumentException();
|
||||
date = tDate;
|
||||
return tDate;
|
||||
}
|
||||
return date.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -351,6 +351,22 @@ group by v.VoucherID, v.VoucherType";
|
||||
}
|
||||
var amount = -1 * (decimal)item.Value[1];
|
||||
var roundoff = Math.Round(amount) - amount;
|
||||
query = @"select count(*) from VoucherSettlement vs
|
||||
where vs.Voucher.VoucherID = :voucherID and (
|
||||
(vs.Amount = :amount and vs.Settled = :soAmount) or
|
||||
(vs.Amount = :roundOff and vs.Settled = :soRoundOff) or
|
||||
(vs.Amount = :paid and vs.Settled = :so))";
|
||||
var existing = _session.CreateQuery(query)
|
||||
.SetParameter("voucherID", item.Key)
|
||||
.SetParameter("amount", amount)
|
||||
.SetParameter("roundOff", roundoff)
|
||||
.SetParameter("paid", -1 * (amount + roundoff))
|
||||
.SetParameter("soAmount", SettleOption.Amount)
|
||||
.SetParameter("soRoundOff", SettleOption.RoundOff)
|
||||
.SetParameter("so", settlementType)
|
||||
.UniqueResult<long>();
|
||||
if (existing == 3)
|
||||
continue;
|
||||
query = @"delete from VoucherSettlement vs where vs.Voucher.VoucherID = :voucherID";
|
||||
_session
|
||||
.CreateQuery(query)
|
||||
@ -450,8 +466,8 @@ order by sum(i.Amount) desc
|
||||
";
|
||||
var list = _session
|
||||
.CreateQuery(query)
|
||||
.SetParameter("startDate", startDate.AddHours(7))
|
||||
.SetParameter("finishDate", finishDate.AddDays(1).AddHours(7))
|
||||
.SetParameter("startDate", startDate)
|
||||
.SetParameter("finishDate", finishDate)
|
||||
.SetParameter("nc", VoucherType.NoCharge)
|
||||
.SetParameter("staff", VoucherType.Staff)
|
||||
.SetParameter("vatLiquor", new Guid("2C8AD8EC-E09A-4194-B348-01243474CF26"))
|
||||
@ -501,7 +517,6 @@ order by i.VatRate
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
public decimal GetServiceTax(DateTime startDate, DateTime finishDate)
|
||||
{
|
||||
const string query = @"
|
||||
@ -560,7 +575,7 @@ order by v.Date desc
|
||||
return (int)qty;
|
||||
}
|
||||
|
||||
public decimal GetSaleAmount(decimal vat, DateTime startDate, DateTime finishDate)
|
||||
private decimal GetSaleAmount(decimal vat, DateTime startDate, DateTime finishDate)
|
||||
{
|
||||
const string query = @"
|
||||
select sum(i.Quantity * i.Price * (1 - i.Discount) * (1 + case when i.IsScTaxable then i.ServiceCharge else 0 end)) as Amount
|
||||
@ -579,109 +594,167 @@ where v.Date >= :startDate and v.Date <= :finishDate and i.VatRate = :vat and v.
|
||||
.UniqueResult();
|
||||
return qty == null ? 0 : (decimal)qty;
|
||||
}
|
||||
public decimal SetSaleQuantity(decimal vat, decimal amount, DateTime startDate, DateTime finishDate)
|
||||
public class DateVatSale
|
||||
{
|
||||
var query = @"
|
||||
select i.InventoryID, 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.VatRate = :vat
|
||||
and v.VoucherType in (:regular, :takeAway)";
|
||||
var list = _session
|
||||
.CreateQuery(query)
|
||||
.SetParameter("startDate", startDate)
|
||||
.SetParameter("finishDate", finishDate)
|
||||
.SetParameter("regular", VoucherType.Regular)
|
||||
.SetParameter("vat", vat)
|
||||
.SetParameter("takeAway", VoucherType.TakeAway)
|
||||
.List<object[]>();
|
||||
Dictionary<Guid, decimal> inventories = new Dictionary<Guid, decimal>();
|
||||
list = Randomize(list);
|
||||
foreach (var item in list)
|
||||
{
|
||||
inventories.Add((Guid)item[0], Convert.ToDecimal(item[1]));
|
||||
}
|
||||
var left = GetSaleAmount(vat, startDate, finishDate) - amount;
|
||||
foreach (var item in inventories)
|
||||
{
|
||||
if (left <= 0)
|
||||
break;
|
||||
var inventoryAmount = item.Value;
|
||||
|
||||
if (inventoryAmount > left)
|
||||
{
|
||||
var ratio = (inventoryAmount - left) / inventoryAmount;
|
||||
query = @"update Inventory set Quantity = Quantity * :ratio where InventoryID = :inventoryID";
|
||||
_session.CreateQuery(query).SetParameter("ratio", ratio).SetParameter("inventoryID", item.Key).ExecuteUpdate();
|
||||
left = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
query = @"delete from Inventory where InventoryID = :inventoryID";
|
||||
_session.CreateQuery(query).SetParameter("inventoryID", item.Key).ExecuteUpdate();
|
||||
left -= inventoryAmount;
|
||||
}
|
||||
}
|
||||
return GetSaleAmount(vat, startDate, finishDate);
|
||||
public DateTime Date { get; set; }
|
||||
public decimal VatRate { get; set; }
|
||||
public decimal Net { get; set; }
|
||||
public decimal Gross { get; set; }
|
||||
}
|
||||
public decimal SetSaleDiscount(decimal vat, decimal amount, DateTime startDate, DateTime finishDate)
|
||||
public List<DateVatSale> GetSaleAmount(DateTime startDate, DateTime finishDate)
|
||||
{
|
||||
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)
|
||||
from Voucher v
|
||||
inner join v.Kots k
|
||||
inner join k.Inventories i
|
||||
where v.Date >= :startDate and v.Date <= :finishDate and v.Void = false and v.VoucherType not in (:nc, :staff)
|
||||
group by i.VatRate
|
||||
";
|
||||
IList<object[]> q;
|
||||
for (var date = startDate.Date; date <= finishDate.Date; date = date.AddDays(1))
|
||||
{
|
||||
q = _session
|
||||
.CreateQuery(query)
|
||||
.SetParameter("startDate", date.AddHours(7))
|
||||
.SetParameter("finishDate", date.AddDays(1).AddHours(7))
|
||||
.SetParameter("nc", VoucherType.NoCharge)
|
||||
.SetParameter("staff", VoucherType.Staff)
|
||||
.List<object[]>();
|
||||
foreach (var item in q)
|
||||
{
|
||||
list.Add(new DateVatSale() { Date = date, VatRate = (decimal)item[0], Net = (decimal)item[1], Gross = (decimal)item[2] });
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
private class InvDate : Inventory
|
||||
{
|
||||
public DateTime Date { get; set; }
|
||||
public decimal Net
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsScTaxable)
|
||||
return Quantity * Price * (1 - Discount) * (1 + ServiceCharge);
|
||||
return Quantity * Price * (1 - Discount);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void SetQuantityAndDiscount(IList<SaleDetailJson> sale, IList<CreditJson> credit, DateTime startDate, DateTime finishDate)
|
||||
{
|
||||
var rand = new Random();
|
||||
var query = @"
|
||||
select i.InventoryID, i.Quantity, i.Discount, i.Quantity * i.Price * (1 - i.Discount) * (1 + case when i.IsScTaxable then i.ServiceCharge else 0 end)
|
||||
select v.Date, i.InventoryID, i.Quantity, i.Price, i.Discount, i.ServiceCharge, i.IsScTaxable, i.ServiceTaxRate, i.VatRate
|
||||
from Voucher v
|
||||
inner join v.Kots k
|
||||
inner join k.Inventories i
|
||||
where v.Date >= :startDate and v.Date <= :finishDate
|
||||
and i.VatRate = :vat and i.Discount < :maxDiscount
|
||||
and v.VoucherType in (:regular, :takeAway)";
|
||||
var list = _session
|
||||
.CreateQuery(query)
|
||||
.SetParameter("startDate", startDate)
|
||||
.SetParameter("finishDate", finishDate)
|
||||
.SetParameter("startDate", startDate.AddHours(7))
|
||||
.SetParameter("finishDate", finishDate.AddDays(1).AddHours(7))
|
||||
.SetParameter("regular", VoucherType.Regular)
|
||||
.SetParameter("vat", vat)
|
||||
.SetParameter("maxDiscount", .9M)
|
||||
.SetParameter("takeAway", VoucherType.TakeAway)
|
||||
.List<object[]>();
|
||||
Dictionary<Guid, object[]> inventories = new Dictionary<Guid, object[]>();
|
||||
list = Randomize(list);
|
||||
foreach (var item in list)
|
||||
List<InvDate> inventories = new List<InvDate>();
|
||||
foreach (var item in Randomize(list))
|
||||
{
|
||||
inventories.Add((Guid)item[0], new object[] { Convert.ToDecimal(item[1]), Convert.ToDecimal(item[2]), Convert.ToDecimal(item[3]) });
|
||||
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]
|
||||
});
|
||||
}
|
||||
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;
|
||||
|
||||
var left = GetSaleAmount(vat, startDate, finishDate) - amount;
|
||||
foreach (var item in inventories)
|
||||
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)
|
||||
{
|
||||
if (left <= 0)
|
||||
break;
|
||||
var invQuantity = (decimal)item.Value[0];
|
||||
var invDiscount = (decimal)item.Value[1];
|
||||
var invNet = (decimal)item.Value[2];
|
||||
var minimum = invDiscount == 0 ? 10 : Convert.ToInt32(invDiscount * 100);
|
||||
var discount = Convert.ToDecimal(rand.Next(minimum, 90)) / 100;
|
||||
if (discount == invDiscount)
|
||||
continue;
|
||||
var reduction = invNet * (discount - invDiscount);
|
||||
foreach (var inv in inventories)
|
||||
{
|
||||
if (sale.Count(x => x.Rate == inv.VatRate) == 0)
|
||||
throw new ArgumentException("Unknown type of vat rate encountered");
|
||||
|
||||
if (reduction > left)
|
||||
{
|
||||
discount = left / invNet;
|
||||
query = @"update Inventory set Discount = :discount where InventoryID = :inventoryID";
|
||||
_session.CreateQuery(query).SetParameter("discount", discount).SetParameter("inventoryID", item.Key).ExecuteUpdate();
|
||||
left = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
query = @"update Inventory set Discount = :discount where InventoryID = :inventoryID";
|
||||
_session.CreateQuery(query).SetParameter("discount", discount).SetParameter("inventoryID", item.Key).ExecuteUpdate();
|
||||
left -= reduction;
|
||||
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.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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return GetSaleAmount(vat, startDate, finishDate);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -19,27 +19,7 @@ namespace Tanshu.Accounts.Repository
|
||||
_session = SessionManager.Session;
|
||||
}
|
||||
|
||||
public IList<SalesAnalysis> GetSaleAnalysis(DateTime startDate, DateTime finishDate)
|
||||
{
|
||||
var start = startDate.Date.AddHours(6);
|
||||
var finish = finishDate.Date.AddDays(1).AddHours(5);
|
||||
List<SalesAnalysis> list = new List<SalesAnalysis>();
|
||||
if (finish <= start)
|
||||
return list;
|
||||
list.AddRange(GetSale(start, finish));
|
||||
list.Add(new SalesAnalysis() { GroupType = " -- ", Amount = 0 });
|
||||
list.AddRange(GetSettlements(start, finish));
|
||||
list.Add(new SalesAnalysis() { GroupType = " -- ", Amount = 0 });
|
||||
var sc = GetServiceCharge(start, finish);
|
||||
if (sc != null)
|
||||
list.Add(sc);
|
||||
var st = GetServiceTax(start, finish);
|
||||
if (st != null)
|
||||
list.Add(st);
|
||||
list.AddRange(GetVat(start, finish));
|
||||
return list;
|
||||
}
|
||||
private IList<SalesAnalysis> GetSale(DateTime startDate, DateTime finishDate)
|
||||
public IList<SalesAnalysis> GetSale(DateTime startDate, DateTime finishDate)
|
||||
{
|
||||
const string query = @"
|
||||
select g.GroupType as GroupType, Sum(i.Quantity * i.Price * (1 - i.Discount)) as Amount
|
||||
@ -74,7 +54,7 @@ order by g.GroupType
|
||||
outList.Add(new SalesAnalysis() { GroupType = "Total Settled", Amount = amount });
|
||||
return outList;
|
||||
}
|
||||
private IList<SalesAnalysis> GetSettlements(DateTime startDate, DateTime finishDate)
|
||||
public IList<SalesAnalysis> GetSettlements(DateTime startDate, DateTime finishDate)
|
||||
{
|
||||
const string query = @"
|
||||
select s.Settled, Sum(s.Amount)
|
||||
@ -99,7 +79,7 @@ order by s.Settled
|
||||
outList.Add(new SalesAnalysis() { GroupType = "Total", Amount = amount });
|
||||
return outList;
|
||||
}
|
||||
private SalesAnalysis GetServiceCharge(DateTime startDate, DateTime finishDate)
|
||||
public SalesAnalysis GetServiceCharge(DateTime startDate, DateTime finishDate)
|
||||
{
|
||||
var query = @"
|
||||
select coalesce(Sum(i.Quantity * i.Price * (1 - i.Discount) * i.ServiceCharge), 0)
|
||||
@ -124,45 +104,19 @@ and vs.Settled != :noCharge and vs.Settled != :unsettled and vs.Settled != :amou
|
||||
return new SalesAnalysis() { GroupType = "Service Charge", Amount = amt };
|
||||
return null;
|
||||
}
|
||||
private SalesAnalysis GetServiceTax(DateTime startDate, DateTime finishDate)
|
||||
public IList<TaxAnalysis> GetServiceTax(DateTime startDate, DateTime finishDate)
|
||||
{
|
||||
var outList = new List<TaxAnalysis>();
|
||||
var query = @"
|
||||
select coalesce(Sum(i.Quantity * i.Price * (1 - i.Discount) * (1 + case when i.IsScTaxable then i.ServiceCharge else 0 end) * i.ServiceTaxRate), 0)
|
||||
select i.ServiceTaxRate, coalesce(Sum(i.Quantity * i.Price * (1 - i.Discount) * (1 + case when i.IsScTaxable then i.ServiceCharge else 0 end) * i.ServiceTaxRate), 0),
|
||||
coalesce(Sum(i.Quantity * i.Price * (1 - i.Discount) * (1 + case when i.IsScTaxable then i.ServiceCharge else 0 end)), 0)
|
||||
from Voucher v
|
||||
inner join v.Kots k
|
||||
inner join k.Inventories i
|
||||
where v.Date >= :startDate and v.Date <= :finishDate and v.Void = false
|
||||
and exists (select Voucher from VoucherSettlement vs where vs.Voucher = v
|
||||
and vs.Settled != :noCharge and vs.Settled != :unsettled and vs.Settled != :amount and vs.Settled != :roundoff and vs.Settled != :staff)
|
||||
";
|
||||
var amt = _session
|
||||
.CreateQuery(query)
|
||||
.SetParameter("startDate", startDate)
|
||||
.SetParameter("finishDate", finishDate)
|
||||
.SetParameter("noCharge", SettleOption.NoCharge)
|
||||
.SetParameter("unsettled", SettleOption.Unsettled)
|
||||
.SetParameter("amount", SettleOption.Amount)
|
||||
.SetParameter("roundoff", SettleOption.RoundOff)
|
||||
.SetParameter("staff", SettleOption.Staff)
|
||||
.UniqueResult<decimal>();
|
||||
if (amt != 0)
|
||||
return new SalesAnalysis() { GroupType = "Service Tax", Amount = amt };
|
||||
return null;
|
||||
}
|
||||
private IList<SalesAnalysis> GetVat(DateTime startDate, DateTime finishDate)
|
||||
{
|
||||
var outList = new List<SalesAnalysis>();
|
||||
var query = @"
|
||||
select va.Name, i.VatRate, coalesce(Sum(i.Quantity * i.Price * (1 - i.Discount) * (1 + case when i.IsScTaxable then i.ServiceCharge else 0 end) * i.VatRate), 0)
|
||||
from Voucher v
|
||||
inner join v.Kots k
|
||||
inner join k.Inventories i
|
||||
inner join i.Vat va
|
||||
where v.Date >= :startDate and v.Date <= :finishDate and v.Void = false
|
||||
and exists (select Voucher from VoucherSettlement vs where vs.Voucher = v
|
||||
and vs.Settled != :noCharge and vs.Settled != :unsettled and vs.Settled != :amount and vs.Settled != :roundoff and vs.Settled != :staff)
|
||||
group by i.VatRate, va.Name
|
||||
";
|
||||
group by i.ServiceTaxRate";
|
||||
var list = _session
|
||||
.CreateQuery(query)
|
||||
.SetParameter("startDate", startDate)
|
||||
@ -174,8 +128,38 @@ group by i.VatRate, va.Name
|
||||
.SetParameter("staff", SettleOption.Staff)
|
||||
.List<object[]>();
|
||||
foreach (var item in list)
|
||||
if ((decimal)item[2] != 0)
|
||||
outList.Add(new SalesAnalysis() { GroupType = string.Format("{0} - {1:#.##%}", (string)item[0], (decimal)item[1]), Amount = (decimal)item[2] });
|
||||
outList.Add(new TaxAnalysis() { Name = string.Format("Service Tax - {0:#.##%;(#.##%);0%}", (decimal)item[0]), TaxRate = (decimal)item[0], TaxAmount = (decimal)item[1], NetSale = (decimal)item[2] });
|
||||
return outList;
|
||||
}
|
||||
public IList<TaxAnalysis> GetVat(DateTime startDate, DateTime finishDate)
|
||||
{
|
||||
var outList = new List<TaxAnalysis>();
|
||||
var query = @"
|
||||
select va.Name, i.VatRate, coalesce(Sum(i.Quantity * i.Price * (1 - i.Discount) * (1 + case when i.IsScTaxable then i.ServiceCharge else 0 end) * i.VatRate), 0),
|
||||
coalesce(Sum(i.Quantity * i.Price * (1 - i.Discount) * (1 + case when i.IsScTaxable then i.ServiceCharge else 0 end)), 0)
|
||||
from Voucher v
|
||||
inner join v.Kots k
|
||||
inner join k.Inventories i
|
||||
inner join i.Vat va
|
||||
where v.Date >= :startDate and v.Date <= :finishDate and v.Void = false
|
||||
and exists (select Voucher from VoucherSettlement vs where vs.Voucher = v
|
||||
and vs.Settled != :noCharge and vs.Settled != :unsettled and vs.Settled != :amount and vs.Settled != :roundoff and vs.Settled != :staff and vs.Settled != :void and vs.Settled != :tip)
|
||||
group by i.VatRate, va.Name
|
||||
";
|
||||
var list = _session
|
||||
.CreateQuery(query)
|
||||
.SetParameter("startDate", startDate)
|
||||
.SetParameter("finishDate", finishDate)
|
||||
.SetParameter("noCharge", SettleOption.NoCharge)
|
||||
.SetParameter("unsettled", SettleOption.Unsettled)
|
||||
.SetParameter("amount", SettleOption.Amount)
|
||||
.SetParameter("roundoff", SettleOption.RoundOff)
|
||||
.SetParameter("staff", SettleOption.Staff)
|
||||
.SetParameter("void", SettleOption.Void)
|
||||
.SetParameter("tip", SettleOption.Tip)
|
||||
.List<object[]>();
|
||||
foreach (var item in list)
|
||||
outList.Add(new TaxAnalysis() { Name = string.Format("{0} - {1:#.##%;(#.##%);0%}", (string)item[0], (decimal)item[1]), TaxRate = (decimal)item[1], TaxAmount = (decimal)item[2], NetSale = (decimal)item[3] });
|
||||
return outList;
|
||||
}
|
||||
}
|
||||
|
||||
10
Tanshu.Accounts.Repository/SettingBI.cs
Normal file
10
Tanshu.Accounts.Repository/SettingBI.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using NHibernate;
|
||||
using Tanshu.Accounts.Entities;
|
||||
|
||||
|
||||
namespace Tanshu.Accounts.Repository
|
||||
{
|
||||
public class SettingBI : UnitOfWork<Setting>
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -119,7 +119,9 @@ namespace Tanshu.Accounts.Repository
|
||||
typeof(PrintLocationMap),
|
||||
typeof(TaxMap),
|
||||
typeof(VoucherSettlementMap),
|
||||
typeof(FoodTableMap)
|
||||
typeof(FoodTableMap),
|
||||
typeof(MachineLocationMap),
|
||||
typeof(SettingMap)
|
||||
};
|
||||
mapper.AddMappings(entities);
|
||||
var mapping = mapper.CompileMappingForAllExplicitlyAddedEntities();
|
||||
|
||||
@ -65,6 +65,8 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="CheckoutBI.cs" />
|
||||
<Compile Include="Cache.cs" />
|
||||
<Compile Include="SettingBI.cs" />
|
||||
<Compile Include="MachineLocationBI.cs" />
|
||||
<Compile Include="ReportsBI.cs" />
|
||||
<Compile Include="GroupBI.cs" />
|
||||
<Compile Include="CustomerBI.cs" />
|
||||
|
||||
Reference in New Issue
Block a user