169 lines
6.4 KiB
C#
169 lines
6.4 KiB
C#
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
|
|
/// <summary>
|
|
/// Loads a Rate from the database.
|
|
/// </summary>
|
|
/// <param name="value">Unique identifier of the Rate .</param>
|
|
/// <param name="isReadOnly">Indicates that object will not be saved later in the code. Use <b>false</b> if you need to save an updated object.</param>
|
|
/// <returns>A <see cref="Rate"/> object retrieved from database.</returns>
|
|
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<Guid, List<Rate>> GetRates(Guid expenditureCategoryId, RateModel.RateType? type)
|
|
{
|
|
return GetRates(new List<Guid>() { expenditureCategoryId }, type);
|
|
}
|
|
|
|
public Dictionary<Guid, List<Rate>> GetRates(List<Guid> expCats, RateModel.RateType? type)
|
|
{
|
|
if (expCats == null || expCats.Count <= 0)
|
|
return new Dictionary<Guid, List<Rate>>();
|
|
|
|
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<Guid, List<Rate>> 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<Guid, List<Rate>> 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<Guid, List<Rate>> MergeRates(List<Rate> globalRates, List<Rate> localRates)
|
|
{
|
|
if (globalRates == null)
|
|
globalRates = new List<Rate>();
|
|
|
|
if (localRates == null)
|
|
localRates = new List<Rate>();
|
|
|
|
var result = new Dictionary<Guid, List<Rate>>();
|
|
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<Rate>();
|
|
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<Guid, List<Rate>> Get4Parents(List<Guid> parents, RateModel.RateType? type)
|
|
{
|
|
if (parents == null || parents.Count <= 0)
|
|
return new Dictionary<Guid, List<Rate>>();
|
|
|
|
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
|
|
}
|
|
} |