using EnVisage.Code.BLL; using EnVisage.Models; using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Threading.Tasks; using System.Web; namespace EnVisage.Code { public class RateManager { private readonly EnVisageEntities _dbContext; private readonly bool _isContexLocal = false; public RateManager(EnVisageEntities dbContext) { if (dbContext == null) { _dbContext = new EnVisageEntities(); _isContexLocal = true; } else { _dbContext = dbContext; } } public void Dispose() { if (_isContexLocal) _dbContext.Dispose(); } #region Public Methods /// /// Loads a Rate from the database. /// /// Unique identifier of the Rate . /// Indicates that object will not be saved later in the code. Use false if you need to save an updated object. /// A object retrieved from database. public Rate Load(Guid? value, bool isReadOnly = true) { if (value == null || value == Guid.Empty) return new Rate(); return isReadOnly ? _dbContext.Rates.AsNoTracking().FirstOrDefault(t => t.Id == value) : _dbContext.Rates.Find(value); } public void Save(RateModel model) { if (model == null) throw new ArgumentNullException("model"); #region Save Rate data Rate dbObj = null; if (model.Id != Guid.Empty) dbObj = _dbContext.Rates.Find(model.Id); if (dbObj == null) { dbObj = new Rate { Id = Guid.NewGuid() }; } model.CopyTo(dbObj); if (model.Id == Guid.Empty) _dbContext.Rates.Add(dbObj); else _dbContext.Entry(dbObj).State = EntityState.Modified; #endregion #region Update Related Scenarios var scenarioManager = new ScenarioManager(_dbContext); scenarioManager.ApplyRateAndRecalculateScenarios(dbObj); if (model.Type == RateModel.RateType.Global) scenarioManager.RecalculateCapacityScenariosRates(dbObj); #endregion if (_isContexLocal) _dbContext.SaveChanges(); } public Dictionary> GetRates(Guid expenditureCategoryId, RateModel.RateType? type) { return GetRates(new List() { expenditureCategoryId }, type); } public Dictionary> GetRates(List expCats, RateModel.RateType? type) { if (expCats == null || expCats.Count <= 0) return new Dictionary>(); var ratesQuery = _dbContext.Rates.Where(x => expCats.Contains(x.ExpenditureCategoryId)); if (type.HasValue) ratesQuery = ratesQuery.Where(x => x.Type == (short)type); return ratesQuery.ToList().GroupBy(x => x.ExpenditureCategoryId) .ToDictionary(x => x.Key, g => g.ToList()); } public decimal GetRateValue(Dictionary> rates, Guid expenditureCategoryId, DateTime currentDate) { if (expenditureCategoryId == Guid.Empty) throw new ArgumentException("Parameter 'expenditureCatetoryId' can not be Guid.Empty"); if (rates == null || rates.Count <= 0) return 0; if (!rates.ContainsKey(expenditureCategoryId)) return 0; var rate = rates[expenditureCategoryId].FirstOrDefault(x => currentDate >= x.StartDate && currentDate <= x.EndDate); return rate != null ? rate.Rate1 : 0; } public Dictionary> GetRates(Guid? scenarioId) { var localRates = _dbContext.Rates.Where(x => x.Type == (short)RateModel.RateType.Derived && x.ParentId == scenarioId).ToList(); var globalRates = _dbContext.Rates.Where(x => x.Type == (short)RateModel.RateType.Global).ToList(); return MergeRates(globalRates, localRates); } public Dictionary> MergeRates(List globalRates, List localRates) { if (globalRates == null) globalRates = new List(); if (localRates == null) localRates = new List(); var result = new Dictionary>(); var expCatsWithLocalRates = localRates.Select(x => x.ExpenditureCategoryId).ToList(); var expCatsWithGlobalRates = globalRates.Select(x => x.ExpenditureCategoryId).ToList(); foreach (var expCatId in expCatsWithLocalRates.Union(expCatsWithGlobalRates)) { var rates = new List(); var expCatLocal = localRates.FindAll(x => x.ExpenditureCategoryId == expCatId); var expCatGlobal = globalRates.FindAll(x => x.ExpenditureCategoryId == expCatId); foreach (var rateDate in expCatLocal.Select(x => x.EndDate).Union(expCatGlobal.Select(x => x.EndDate)).OrderBy(x => x)) { var localRate = expCatLocal.FirstOrDefault(x => x.EndDate == rateDate); var globalRate = expCatGlobal.FirstOrDefault(x => x.EndDate == rateDate); rates.Add(localRate == null ? globalRate : localRate); } result.Add(expCatId, rates); } return result; } public Dictionary> Get4Parents(List parents, RateModel.RateType? type) { if (parents == null || parents.Count <= 0) return new Dictionary>(); var query = _dbContext.Rates.Where(x => x.ParentId.HasValue && parents.Contains(x.ParentId.Value)); if (type.HasValue) query = query.Where(x => x.Type == (short)type.Value); return query.ToList() .GroupBy(x => x.ParentId.Value) .ToDictionary(x => x.Key, g => g.ToList()); } #endregion } }