EnVisageOnline/Beta/Source/EnVisage/Models/ResourceModel.cs

245 lines
7.5 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using EnVisage.Code;
namespace EnVisage.Models
{
public class PeopleResourceModel : IBaseModel<PeopleResource>
{
public class CapacityValues
{
public DateTime WeekEnding { get; set; }
public decimal Quantity { get; set; }
public decimal Cost { get; set; }
public Guid ExpCatId { get; set; }
}
private Dictionary<DateTime, CapacityValues> weeklyCapacity = null;
#region Properties
public Guid Id { get; set; }
[Required]
[StringLength(250, MinimumLength = 1)]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required]
[StringLength(250, MinimumLength = 1)]
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Display(Name = "Employee Status")]
public bool IsActiveEmployee { get; set; }
[Required]
[Display(Name = "Start Date")]
[DataType(System.ComponentModel.DataAnnotations.DataType.Date)]
public DateTime StartDate { get; set; }
[Required]
[Display(Name = "End Date")]
[DataType(System.ComponentModel.DataAnnotations.DataType.Date)]
public DateTime EndDate { get; set; }
[Display(Name = "Team")]
public Guid? TeamId { get; set; }
public Team Team { get; set; }
[Display(Name = "Expenditure Category")]
public Guid ExpenditureCategoryId { get; set; }
[Display(Name = "Resource Capacity")]
public Dictionary<DateTime, CapacityValues> WeeklyCapacities {
get
{
if (weeklyCapacity == null)
weeklyCapacity = GetResourceWeeklyCapacity(null);
return weeklyCapacity;
}
}
public bool ChangeCapacity { get; set; }
public bool FullTimeResource { get; set; }
public ExpenditureCategory ExpenditureCategory { get; set; }
public List<VacationModel> Vacations { get; set; }
public List<TrainingModel> Trainings { get; set; }
public List<Guid> SubstituteResources { get; set; }
[Display(Name = "Create another")]
public bool AddMore { get; set; }
//[Display(Name = "Resources")]
//[UIHint("Resources")]
//public List<Guid> Resources { get; set; }
//[Display(Name = "Training Name")]
//public string TrainingName { get; set; }
//[Required]
//[Display(Name = "Start Date")]
//[DataType(System.ComponentModel.DataAnnotations.DataType.Date)]
//public DateTime TrainingStartDate { get; set; }
//[Required]
//[Display(Name = "End Date")]
//[DataType(System.ComponentModel.DataAnnotations.DataType.Date)]
//public DateTime TrainingEndDate { get; set; }
//[Display(Name = "Duration")]
//public int TrainingDuration { get; set; }
//[Display(Name = "Training Type")]
//public Guid TrainingTypeID { get; set; }
//[Display(Name = "Cost")]
//public decimal TrainingCost { get; set; }
//[Display(Name = "% Time Allocated")]
//public decimal TrainingTimeAllocated { get; set; }
public TrainingModel Training { get; set; }
#endregion
#region Constructor
public PeopleResourceModel()
{
IsActiveEmployee = true;
StartDate = DateTime.Today;
EndDate = DateTime.Today.AddYears(1);
Training = new TrainingModel(){
TrainingStartDate = DateTime.Today,
TrainingEndDate = DateTime.Today.AddYears(1),
Resources = new List<Guid>()
};
}
#endregion
#region Methods
/// <summary>
/// Casts a <see cref="Resource"/> obect to the object of type <see cref="PeopleResourceModel"/>.
/// </summary>
/// <param name="obj">A <see cref="Resource"/> object.</param>
/// <returns>A <see cref="PeopleResourceModel"/> object filled with data from db.</returns>
public static explicit operator PeopleResourceModel(PeopleResource obj)
{
if (obj == null)
return null;
var model = new PeopleResourceModel()
{
Id = obj.Id,
ExpenditureCategoryId = obj.ExpenditureCategoryId,
ExpenditureCategory = obj.ExpenditureCategory,
TeamId = obj.TeamId,
Team = obj.Team,
FirstName = obj.FirstName,
LastName = obj.LastName,
IsActiveEmployee = obj.IsActiveEmployee,
StartDate = obj.StartDate,
EndDate = obj.EndDate
};
model.TrimStringProperties();
return model;
}
/// <summary>
/// Copies data from model to DAL object.
/// </summary>
/// <param name="dbObj">A target DAL object.</param>
public void CopyTo(PeopleResource dbObj)
{
if (dbObj == null)
throw new ArgumentNullException();
dbObj.FirstName = FirstName;
dbObj.LastName = LastName;
dbObj.IsActiveEmployee = IsActiveEmployee;
dbObj.TeamId = TeamId;
dbObj.ExpenditureCategoryId = ExpenditureCategoryId;
dbObj.StartDate = StartDate;
dbObj.EndDate = EndDate;
}
/// <summary>
/// Returns the dictionary containing resource capacity distribution over weeks
/// </summary>
/// <param name="globalRates">Global rates. Can be null or empty - in this case method will retrieve the data itself.
/// Dictionary format: key is expenditure category id; dictionary item is list of rates (can be unordered)</param>
/// <returns></returns>
public Dictionary<DateTime, CapacityValues> GetResourceWeeklyCapacity(Dictionary<Guid, List<Rate>> globalRates)
{
Dictionary<DateTime, CapacityValues> dict = new Dictionary<DateTime, CapacityValues>();
decimal? weeklyCapVal = null;
var context = new EnVisageEntities();
// get week capacity for resource's Expenditure Category
if (ExpenditureCategory != null && ExpenditureCategory.UOM != null)
weeklyCapVal = ExpenditureCategory.UOM.UOMValue;
else
{
var uomId = context.ExpenditureCategory.FirstOrDefault(x => x.Id == ExpenditureCategoryId).UOMId;
weeklyCapVal = context.UOMs.FirstOrDefault(x => x.Id == uomId).UOMValue;
}
// get weekending dates between resource Start and End dates
var weekendings = context.FiscalCalendars
.Where(x => x.Type == (int)EnVisage.Models.FiscalCalendarModel.FiscalYearType.Week &&
x.StartDate >= StartDate && x.EndDate <= EndDate).Select(x => x.EndDate);
//Get global rates if they are not supplied
if (globalRates == null || globalRates.Count == 0)
{
globalRates = new Dictionary<Guid, List<Rate>>();
globalRates.Add(ExpenditureCategory.Id,
context.Rates.Where(r => r.ExpenditureCategoryId == ExpenditureCategory.Id && r.Type == (short)EnVisage.Models.RateModel.RateType.Global).OrderBy(r => r.StartDate).ThenBy(r => r.EndDate).ToList());
}
List<Rate> rates = new List<Rate>();
if (globalRates.ContainsKey(ExpenditureCategory.Id))
rates = globalRates[ExpenditureCategory.Id];
//we need to sort rates list by startdate asc and enddate asc to make sure we can go with single loop
List<Rate> orderedRates = rates.OrderBy(r => r.StartDate).ThenBy(r => r.EndDate).ToList();
foreach (var week in weekendings)
{
if (!dict.ContainsKey(week))
{
decimal rate = 0.0M;
for (int i = 0; i < orderedRates.Count; i++)
{
Rate r = orderedRates[i];
if (week >= r.StartDate && week <= r.EndDate)
{
rate = r.Rate1;
break;
}
}
decimal cost = weeklyCapVal.HasValue ? weeklyCapVal.Value * rate : 0;
dict.Add(week, new CapacityValues()
{
Quantity = weeklyCapVal.HasValue ? weeklyCapVal.Value : 0,
Cost = cost,
WeekEnding = week,
ExpCatId = ExpenditureCategoryId
});
}
}
return dict;
}
#endregion
}
}