525 lines
17 KiB
C#
525 lines
17 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using System.Linq;
|
|
using EnVisage.Code;
|
|
using System.Web.Mvc;
|
|
using EnVisage.Code.BLL;
|
|
|
|
namespace EnVisage.Models
|
|
{
|
|
/// <summary>
|
|
/// Information about existance of allocations for resource
|
|
/// </summary>
|
|
public class PeopleResourceAllocationsInfoModel
|
|
{
|
|
public bool HasAllocations { get; set; }
|
|
public DateTime? AllocationsMinDate { get; set; }
|
|
public DateTime? AllocationsMaxDate { get; set; }
|
|
public long? AllocationsMinDateMs
|
|
{
|
|
get
|
|
{
|
|
return AllocationsMinDate.HasValue ? Utils.ConvertToUnixDate(AllocationsMinDate.Value) : (long?)null;
|
|
}
|
|
}
|
|
public long? AllocationsMaxDateMs
|
|
{
|
|
get
|
|
{
|
|
return AllocationsMaxDate.HasValue ? Utils.ConvertToUnixDate(AllocationsMaxDate.Value) : (long?)null;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents information about people resource existed in one of the teams. TeamId, StartDate and EndDate store info about only one of teams according to PeopleResource2Team database record.
|
|
/// </summary>
|
|
public class PeopleResourceModel : IBaseModel<PeopleResource>, IValidatableObject
|
|
{
|
|
public class CapacityValues
|
|
{
|
|
public DateTime WeekEnding { get; set; }
|
|
public decimal Quantity { get; set; }
|
|
public decimal Cost { get; set; }
|
|
}
|
|
|
|
public class TeamInfo
|
|
{
|
|
public Guid Id { get; set; }
|
|
public DateTime ChangeDate { get; set; }
|
|
public string Name { get; set; }
|
|
}
|
|
|
|
#region Properties
|
|
public Guid Id { get; set; }
|
|
public bool IsNew { get; set; }
|
|
|
|
[Required]
|
|
[Display(Name = "Effective Date of Change")]
|
|
[DataType(DataType.Date)]
|
|
public DateTime EffectiveChangeDate { 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; }
|
|
|
|
// For display in lists and forms
|
|
public string DisplayName
|
|
{
|
|
get
|
|
{
|
|
return String.Format("{0} {1}",
|
|
!String.IsNullOrEmpty(FirstName) ? FirstName : String.Empty,
|
|
!String.IsNullOrEmpty(LastName) ? LastName : String.Empty).Trim();
|
|
}
|
|
}
|
|
|
|
// For sorting in lists
|
|
public string SortingKey
|
|
{
|
|
get
|
|
{
|
|
return String.Format("{0} {1}",
|
|
!String.IsNullOrEmpty(LastName) ? LastName : String.Empty,
|
|
!String.IsNullOrEmpty(FirstName) ? FirstName : String.Empty).Trim();
|
|
}
|
|
}
|
|
|
|
[Required]
|
|
[StringLength(320, MinimumLength = 1)]
|
|
[Display(Name = "Email Address")]
|
|
[Remote("IsUnique", "PeopleResource", AdditionalFields = "Id", ErrorMessage = "This email has already been assigned to another resource.", HttpMethod = "POST")]
|
|
public string EmailAddress { get; set; }
|
|
|
|
[MaxLength(100)]
|
|
[Display(Name = "Employee ID")]
|
|
public string EmployeeID { get; set; }
|
|
|
|
[Display(Name = "Employee Status")]
|
|
public bool IsActiveEmployee { get; set; }
|
|
|
|
[Display(Name = "On Deactivation")]
|
|
public bool ReassignOnDeactivation { get; set; }
|
|
|
|
[Required]
|
|
[Display(Name = "Start Date")]
|
|
[DataType(DataType.Date)]
|
|
public DateTime StartDate { get; set; }
|
|
|
|
[Display(Name = "End Date")]
|
|
[DataType(DataType.Date)]
|
|
public DateTime? EndDate { get; set; }
|
|
|
|
[Display(Name = "Team")]
|
|
public Guid? TeamId { get; set; }
|
|
|
|
// Information about pended team change
|
|
public TeamInfo TeamChangeQueued { get; set; }
|
|
|
|
public Team Team { get; set; }
|
|
|
|
[Display(Name = "Work Week")]
|
|
public Guid WorkWeekId { get; set; }
|
|
|
|
[Display(Name = "Expenditure Category")]
|
|
public Guid ExpenditureCategoryId { get; set; }
|
|
public PeopleResourceAllocationsInfoModel ResourceScenarioAllocationsInfo { get; set; }
|
|
public PeopleResourceAllocationsInfoModel ResourceActualsInfo { get; set; }
|
|
public PeopleResourceAllocationsInfoModel ResourceMixAllocationsInfo { get; set; }
|
|
|
|
public bool ChangeCapacity { get; set; }
|
|
|
|
public bool PermanentResource { get; set; }
|
|
|
|
public ExpenditureCategory ExpenditureCategory { get; set; }
|
|
|
|
public List<NonProjectTimeListItemModel> NonProjectTimes { get; set; }
|
|
|
|
public List<Guid> SubstituteResources { get; set; }
|
|
|
|
public List<PeopleResourceReassignmentModel> AllocationsReassignmentPlan { get; set; }
|
|
|
|
/// <summary>
|
|
/// All teams, the resource is a member of
|
|
/// </summary>
|
|
public List<TeamMembershipModel> Teams { get; set; }
|
|
|
|
[Display(Name = "Create another")]
|
|
public bool AddMore { get; set; }
|
|
public short TeamAllocation { get; set; }
|
|
|
|
#endregion
|
|
#region Constructor
|
|
public PeopleResourceModel()
|
|
{
|
|
Id = Guid.NewGuid();
|
|
IsActiveEmployee = true;
|
|
|
|
var utcToday = DateTime.UtcNow.Date;
|
|
StartDate = utcToday;
|
|
EndDate = utcToday.AddYears(1).Date;
|
|
EffectiveChangeDate = utcToday;
|
|
}
|
|
#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,
|
|
IsNew = false,
|
|
ExpenditureCategoryId = obj.ExpenditureCategoryId,
|
|
ExpenditureCategory = obj.ExpenditureCategory,
|
|
FirstName = obj.FirstName,
|
|
LastName = obj.LastName,
|
|
IsActiveEmployee = obj.IsActiveEmployee,
|
|
StartDate = obj.StartDate,
|
|
EndDate = obj.EndDate,
|
|
EmailAddress = obj.Email,
|
|
EmployeeID = obj.EmployeeID,
|
|
WorkWeekId = obj.WorkWeekId,
|
|
PermanentResource = obj.EndDate >= Constants.FISCAL_CALENDAR_MAX_DATE
|
|
};
|
|
|
|
model.TrimStringProperties();
|
|
return model;
|
|
}
|
|
|
|
/// <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>
|
|
/// <param name="cat">An <see cref="ExpenditureCategory"/> object, related to the specified resource <paramref name="obj"/>.</param>
|
|
/// <param name="team">A <see cref="Team"/> object, related to the specified resource <paramref name="obj"/>.</param>
|
|
/// <returns>A <see cref="PeopleResourceModel"/> object filled with data from db.</returns>
|
|
public static PeopleResourceModel GetPeopleResourceModel(VW_TeamResource obj, ExpenditureCategory cat, Team team)
|
|
{
|
|
if (obj == null)
|
|
return null;
|
|
var model = new PeopleResourceModel()
|
|
{
|
|
Id = obj.Id,
|
|
IsNew = false,
|
|
ExpenditureCategoryId = obj.ExpenditureCategoryId,
|
|
ExpenditureCategory = cat,
|
|
TeamId = obj.TeamId,
|
|
Team = team,
|
|
FirstName = obj.FirstName,
|
|
LastName = obj.LastName,
|
|
IsActiveEmployee = obj.IsActiveEmployee,
|
|
StartDate = obj.TeamStartDate,
|
|
EndDate = obj.TeamEndDate,
|
|
EmailAddress = obj.Email,
|
|
EmployeeID = obj.EmployeeID,
|
|
WorkWeekId = obj.WorkWeekId,
|
|
TeamAllocation = obj.Allocation,
|
|
};
|
|
|
|
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.ExpenditureCategoryId = ExpenditureCategoryId;
|
|
dbObj.StartDate = StartDate;
|
|
dbObj.EndDate = EndDate.HasValue ? EndDate.Value : Constants.FISCAL_CALENDAR_MAX_DATE;
|
|
dbObj.EmployeeID = EmployeeID;
|
|
dbObj.Email = EmailAddress;
|
|
dbObj.WorkWeekId = WorkWeekId;
|
|
}
|
|
|
|
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
|
{
|
|
if (PeopleResourcesManager.ResourceByEmailExists(EmailAddress, Id))
|
|
yield return new ValidationResult(string.Format(Constants.ERROR_DUPLICATE_EMAIL), new[] { "EmailAddress" });
|
|
if (!PermanentResource && EndDate.HasValue && EndDate.Value < StartDate)
|
|
yield return new ValidationResult("End Date must be later or equal to Start Date", new[] { "EndDate" });
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Model for Resource's Expenditure Category change operations
|
|
/// </summary>
|
|
public class PeopleResourceExpenditureChangeModel
|
|
{
|
|
public Guid ResourceId { get; set; }
|
|
public Guid ExpenditureCategoryId { get; set; }
|
|
public bool ChangePlannedCapacity { get; set; }
|
|
public Guid CurrentExpenditureCategoryId { get; set; }
|
|
public string CurrentExpenditureCategoryName { get; set; }
|
|
|
|
public PeopleResourceExpenditureChangeModel()
|
|
{
|
|
}
|
|
|
|
public PeopleResourceExpenditureChangeModel(PeopleResourceModel resourceModel)
|
|
{
|
|
ResourceId = resourceModel.Id;
|
|
ExpenditureCategoryId = resourceModel.ExpenditureCategoryId;
|
|
CurrentExpenditureCategoryId = resourceModel.ExpenditureCategoryId;
|
|
ChangePlannedCapacity = resourceModel.ChangeCapacity;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Model for Resource allocations reassignment plan
|
|
/// </summary>
|
|
public class PeopleResourceReassignmentModel
|
|
{
|
|
public enum MoveAction
|
|
{
|
|
NoAction = 0,
|
|
MoveToNewTeam = 1,
|
|
MoveToResource = 2,
|
|
DropAssignments = 3
|
|
}
|
|
|
|
public class TeamSubstitutionOptions
|
|
{
|
|
public Guid TeamId { get; set; }
|
|
public string TeamName { get; set; }
|
|
public bool IsCurrentTeam { get; set; }
|
|
public List<SelectListItem> Resources { get; set; }
|
|
|
|
public TeamSubstitutionOptions()
|
|
{
|
|
Resources = new List<SelectListItem>();
|
|
}
|
|
|
|
}
|
|
|
|
public Guid ProjectId { get; set; }
|
|
public string ProjectName { get; set; }
|
|
public bool ProjectHasDestTeam { get; set; }
|
|
public MoveAction Action { get; set; }
|
|
public string DestResource { get; set; }
|
|
public List<TeamSubstitutionOptions> SubstitutionOptions { get; set; }
|
|
|
|
public PeopleResourceReassignmentModel()
|
|
{
|
|
Action = MoveAction.NoAction;
|
|
SubstitutionOptions = new List<TeamSubstitutionOptions>();
|
|
}
|
|
}
|
|
|
|
public class PeopleResourceWithAllocationModel
|
|
{
|
|
public Guid Id { get; set; }
|
|
public Guid ExpenditureCategoryId { get; set; }
|
|
public Guid OwnExpenditureCategoryId { get; set; }
|
|
public Guid TeamId { get; set; }
|
|
public Guid WorkWeekId { get; set; }
|
|
public string FirstName { get; set; }
|
|
public string LastName { get; set; }
|
|
public DateTime StartDate { get; set; }
|
|
public DateTime? EndDate { get; set; }
|
|
public List<ResourceAllocationModel> Allocations { get; set; }
|
|
|
|
public PeopleResourceWithAllocationModel()
|
|
{
|
|
Allocations = new List<ResourceAllocationModel>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes a <see cref="PeopleResourceWithAllocationModel"/> object with values from <see cref="VW_TeamResource/> object.
|
|
/// </summary>
|
|
/// <param name="resource">An instance of <see cref="VW_TeamResource"/> object used to initialize an object.</param>
|
|
/// <remarks>
|
|
/// Note that Start and End dates of <see cref="PeopleResourceWithAllocationModel"/> object will be initialized with TeamStartDate and TeamEndDate
|
|
/// properties of <see cref="VW_TeamResource"/> object.
|
|
/// </remarks>
|
|
public PeopleResourceWithAllocationModel(VW_TeamResource resource)
|
|
: this()
|
|
{
|
|
if (resource == null)
|
|
return;
|
|
|
|
Id = resource.Id;
|
|
ExpenditureCategoryId = resource.ExpenditureCategoryId;
|
|
OwnExpenditureCategoryId = resource.ExpenditureCategoryId;
|
|
TeamId = resource.TeamId;
|
|
FirstName = resource.FirstName;
|
|
LastName = resource.LastName;
|
|
StartDate = resource.TeamStartDate;
|
|
EndDate = resource.TeamEndDate;
|
|
WorkWeekId = resource.WorkWeekId;
|
|
}
|
|
|
|
public PeopleResourceWithAllocationModel(VW_TeamResource resource, List<PeopleResourceAllocation> allocations)
|
|
: this(resource)
|
|
{
|
|
if (allocations == null || allocations.Count <= 0)
|
|
return;
|
|
|
|
Allocations = allocations.Select(x => new ResourceAllocationModel(x)).ToList();
|
|
}
|
|
}
|
|
|
|
public class ResourceAllocationModel
|
|
{
|
|
public Guid PeopleResourceId { get; set; }
|
|
public Guid ScenarioId { get; set; }
|
|
public Guid TeamId { get; set; }
|
|
public Guid ExpenditureCategoryId { get; set; }
|
|
public DateTime WeekEndingDate { get; set; }
|
|
public decimal Quantity { get; set; }
|
|
|
|
public ResourceAllocationModel() { }
|
|
public ResourceAllocationModel(PeopleResourceAllocation allocation)
|
|
{
|
|
if (allocation == null)
|
|
return;
|
|
|
|
PeopleResourceId = allocation.PeopleResourceId;
|
|
ScenarioId = allocation.ScenarioId;
|
|
TeamId = allocation.TeamId;
|
|
ExpenditureCategoryId = allocation.ExpenditureCategoryId;
|
|
WeekEndingDate = allocation.WeekEndingDate;
|
|
Quantity = allocation.Quantity;
|
|
}
|
|
}
|
|
|
|
public class ResourceActualAllocationModel
|
|
{
|
|
public Guid PeopleResourceId { get; set; }
|
|
public Guid ActualScenarioId { get; set; }
|
|
public Guid ScenarioDetailId { get; set; }
|
|
public Guid ExpenditureCategoryId { get; set; }
|
|
public DateTime WeekEndingDate { get; set; }
|
|
public decimal Quantity { get; set; }
|
|
public decimal Cost { get; set; }
|
|
}
|
|
|
|
public class TeamMembershipModel
|
|
{
|
|
public Guid Id;
|
|
public Guid TeamId;
|
|
public DateTime StartDate;
|
|
public DateTime? EndDate;
|
|
|
|
public bool IsInRange(DateTime dt)
|
|
{
|
|
return (StartDate <= dt) && (!EndDate.HasValue || (EndDate.Value >= dt));
|
|
}
|
|
}
|
|
|
|
public class PeopleResourceReassignModel
|
|
{
|
|
public DateTime EffectiveChangeDate { get; set; }
|
|
public List<PeopleResourceReassignmentModel> AllocationsReassignmentPlan { get; set; }
|
|
}
|
|
|
|
#region Resources with teams models
|
|
|
|
public class PeopleResourceWithTeamsModelBase<T> where T : class
|
|
{
|
|
public Guid Id { get; set; }
|
|
public string FirstName { get; set; }
|
|
public string LastName { get; set; }
|
|
public Guid ExpenditureCategoryId { get; set; }
|
|
public List<T> Teams { get; set; }
|
|
}
|
|
|
|
public class PeopleResourceWithTeamsDataModel : PeopleResourceWithTeamsModelBase<PeopleResourceTeamModel>
|
|
{
|
|
}
|
|
|
|
public class PeopleResourceWithTeamsApiModel : PeopleResourceWithTeamsModelBase<PeopleResourceTeamApiModel>
|
|
{
|
|
#region Constructors
|
|
|
|
public PeopleResourceWithTeamsApiModel()
|
|
{
|
|
|
|
}
|
|
|
|
public PeopleResourceWithTeamsApiModel(PeopleResourceWithTeamsDataModel entity)
|
|
: this()
|
|
{
|
|
if (entity == null)
|
|
throw new ArgumentNullException("entity");
|
|
|
|
Id = entity.Id;
|
|
FirstName = entity.FirstName;
|
|
LastName = entity.LastName;
|
|
ExpenditureCategoryId = entity.ExpenditureCategoryId;
|
|
|
|
if (entity.Teams != null)
|
|
{
|
|
Teams = entity.Teams.Select(x => new PeopleResourceTeamApiModel(x))
|
|
.ToList();
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
public class PeopleResourceTeamModel
|
|
{
|
|
public Guid TeamId { get; set; }
|
|
public bool ReadOnly { get; set; }
|
|
public DateTime StartDate { get; set; }
|
|
public DateTime? EndDate { get; set; }
|
|
}
|
|
|
|
public class PeopleResourceTeamApiModel
|
|
{
|
|
public Guid TeamId { get; set; }
|
|
public bool ReadOnly { get; set; }
|
|
public long StartDate { get; set; }
|
|
public long? EndDate { get; set; }
|
|
|
|
#region Constructors
|
|
|
|
public PeopleResourceTeamApiModel()
|
|
{
|
|
|
|
}
|
|
|
|
public PeopleResourceTeamApiModel(PeopleResourceTeamModel entity)
|
|
: this()
|
|
{
|
|
if (entity == null)
|
|
throw new ArgumentNullException("entity");
|
|
|
|
TeamId = entity.TeamId;
|
|
ReadOnly = entity.ReadOnly;
|
|
StartDate = Utils.ConvertToUnixDate(entity.StartDate);
|
|
|
|
if (entity.EndDate.HasValue)
|
|
EndDate = Utils.ConvertToUnixDate(entity.EndDate.Value);
|
|
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
#endregion
|
|
} |