410 lines
15 KiB
C#
410 lines
15 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using System.Web.Mvc;
|
|
using EnVisage.Code;
|
|
using System.Linq;
|
|
using EnVisage.Models.ValidationAttributes.Scenarios;
|
|
using EnVisage.Models.Cache;
|
|
using EnVisage.Code.BLL;
|
|
using EnVisage.Models.ProjectDependencies;
|
|
|
|
namespace EnVisage.Models
|
|
{
|
|
public class ScenarioDetailModel : IBaseModel<Scenario>
|
|
{
|
|
#region Properties
|
|
public Guid Id { get; set; }
|
|
|
|
[Required]
|
|
[AllowHtml]
|
|
[MaxLength(100)]
|
|
public string Name { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets an Id of the template.
|
|
/// </summary>
|
|
[Display(Name = "Template")]
|
|
public Guid TemplateId { get; set; }
|
|
|
|
[Display(Name = "Project Name")]
|
|
public string ProjectName { get; set; }
|
|
|
|
[Display(Name = "Project Deadline")]
|
|
[DataType(DataType.Date)]
|
|
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
|
|
public DateTime? ProjectDeadline { get; set; }
|
|
|
|
[Display(Name = "Part Name")]
|
|
public string PartName { get; set; }
|
|
/// <summary>
|
|
/// Gets or sets an Id of the project.
|
|
/// </summary>
|
|
public Guid ParentId { get; set; }
|
|
/// <summary>
|
|
/// Gets or sets a color that will be used for scenario in reports.
|
|
/// </summary>
|
|
[MaxLength(8)]
|
|
public string Color { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets a type of scenario.
|
|
/// </summary>
|
|
public ScenarioType? Type { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets a scenario of scenario.
|
|
/// </summary>
|
|
public ScenarioStatus? Status { get; set; }
|
|
|
|
[Display(Name = "Active Scenario")]
|
|
public bool IsActiveScenario { get; set; }
|
|
|
|
[DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:MM/dd/yy}", ApplyFormatInEditMode = true)]
|
|
[Display(Name = "Scenario Start Date")]
|
|
[Required]
|
|
[ScenarioStartDateValidator]
|
|
public DateTime? StartDate { get; set; }
|
|
|
|
[DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:MM/dd/yy}", ApplyFormatInEditMode = true)]
|
|
[Display(Name = "Scenario End Date")]
|
|
[Required]
|
|
[ScenarioEndDateValidator]
|
|
[DateGreaterThanOrEqual("StartDate", "Scenario End Date should not be less than Start Date")]
|
|
public DateTime? EndDate { get; set; }
|
|
|
|
[DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:MM/dd/yy}", ApplyFormatInEditMode = true)]
|
|
[Display(Name = "Milestone Start Date")]
|
|
public DateTime? MilestoneStartDate { get; set; }
|
|
|
|
[Display(Name = "Growth Scenario?")]
|
|
public bool GrowthScenario { get; set; }
|
|
|
|
[Display(Name = "Total Milestones")]
|
|
// not editable
|
|
//[Range(1, 2147483647)]
|
|
public int TotalMilestones { get; set; }
|
|
|
|
[Display(Name = "Calculated Duration (weeks)")]
|
|
public int? Duration { get; set; }
|
|
|
|
public IList<ScenarioModel.ExpenditureItem> Expenditures { get; set; }
|
|
|
|
public IList<ScenarioModel.ExpenditureItem> ScenarioExpenditures { get; set; }
|
|
|
|
public RatesModel RatesModel { get; set; }
|
|
|
|
public string BackUrl { get; set; }
|
|
public string BackName { get; set; }
|
|
public string ActiveTab { get; set; }
|
|
public bool HasActuals { get; set; }
|
|
public long ActualsStartDate { get; set; }
|
|
public long ActualsEndDate { get; set; }
|
|
public bool NeedToRecalculateScenarioDetails { get; set; }
|
|
|
|
/// <summary>
|
|
/// True, if parent project has dependencies with other projects
|
|
/// </summary>
|
|
public bool ProjectHasDependencies { get; set; }
|
|
public DateTime? StartDateConstraint { get; set; }
|
|
public DateTime? EndDateConstraint { get; set; }
|
|
public long? StartDateConstraintMs => StartDateConstraint.HasValue ? Utils.ConvertToUnixDate(StartDateConstraint.Value.ToUniversalTime()) : (long?)null;
|
|
|
|
public long? EndDateConstraintMs => EndDateConstraint.HasValue ? Utils.ConvertToUnixDate(EndDateConstraint.Value.ToUniversalTime()) : (long?)null;
|
|
|
|
[Display(Name = "Scenario Type")]
|
|
public bool IsBottomUp { get; set; }
|
|
public ScenarioFinInfoModel FinInfo { get; set; }
|
|
public List<UDFValueCollection> UserDefinedFields { get; set; }
|
|
public string WorkFlowCommand { get; set; }
|
|
[Display(Name = "Workflow State")]
|
|
public string WorkFlowState { get; set; }
|
|
[Display(Name = "Workflow Process")]
|
|
public string WorkFlowScheme { get; set; }
|
|
public Guid ProjectId { get; internal set; }
|
|
public IReadOnlyCollection<SelectListItem> Projects { get; internal set; }
|
|
#endregion
|
|
|
|
#region Constructors
|
|
public ScenarioDetailModel()
|
|
{
|
|
Expenditures = new List<ScenarioModel.ExpenditureItem>();
|
|
RatesModel = new RatesModel();
|
|
FinInfo = new ScenarioFinInfoModel();
|
|
var udfMan = new UDFManager(new EnVisageEntities());
|
|
UserDefinedFields = udfMan.LoadCollection(Guid.Empty, UserDefinedFieldDomain.Scenario);
|
|
}
|
|
#endregion
|
|
|
|
#region Methods
|
|
|
|
/// <summary>
|
|
/// Copies data from model to DAL object.
|
|
/// </summary>
|
|
/// <param name="dbObj">A target DAL object.</param>
|
|
public void CopyTo(Scenario dbObj)
|
|
{
|
|
if (dbObj == null)
|
|
throw new ArgumentNullException();
|
|
dbObj.Name = Name;
|
|
|
|
// SA. Fixed bug ENV-707. Begin fix
|
|
dbObj.Color = !string.IsNullOrEmpty(Color) ? Color.Replace("#", "") : null;
|
|
// End fix ENV-707
|
|
|
|
dbObj.Type = Type.GetHashCode();
|
|
dbObj.Status = IsActiveScenario ? Code.ScenarioStatus.Active.GetHashCode() : ScenarioStatus.Inactive.GetHashCode();
|
|
dbObj.IsBottomUp = IsBottomUp;
|
|
dbObj.ShotStartDate = MilestoneStartDate;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
public class LaborMaterialsCostInfo
|
|
{
|
|
public decimal Labor { get; set; }
|
|
public decimal Materials { get; set; }
|
|
public decimal Total { get; set; }
|
|
public string LaborAndMaterialSplit
|
|
{
|
|
get
|
|
{
|
|
if (Labor == 0 && Materials == 0)
|
|
return "0/0";
|
|
|
|
decimal laborPart = Math.Round((Labor / (Labor + Materials)) * 100, 2);
|
|
return string.Format("{0:G29}/{1:G29}", laborPart, 100 - laborPart);
|
|
}
|
|
}
|
|
}
|
|
|
|
public class ScenarioCopyModel
|
|
{
|
|
public Guid ScenarioId { get; set; }
|
|
[Required]
|
|
[Display(Name = "Target Project")]
|
|
public Guid TargetProjectId { get; set; }
|
|
public ScenarioStatus TargetStatus { get; set; }
|
|
public bool includeCostSavings { get; set; }
|
|
public bool hasCostSavings { get; set; }
|
|
public IReadOnlyCollection<SelectListItem> Projects { get; set; }
|
|
}
|
|
|
|
public class ScenarioDetailsCalendarModel
|
|
{
|
|
#region Properties
|
|
|
|
public Guid Id { get; set; }
|
|
public string Name { get; set; }
|
|
public Guid ParentId { get; set; }
|
|
public Guid? TemplateId { get; set; }
|
|
public long StartDate { get; set; }
|
|
public long EndDate { get; set; }
|
|
public decimal ProjectedRevenue { get; set; }
|
|
public bool GrowthScenario { get; set; }
|
|
public ScenarioType Type { get; set; }
|
|
public bool UseLMMargin { get; set; }
|
|
public decimal? GrossMargin { get; set; }
|
|
public decimal? LMMargin { get; set; }
|
|
public int Duration { get; set; }
|
|
public decimal TDDirectCosts { get; set; }
|
|
public decimal CGSplit { get; set; }
|
|
public decimal EFXSplit { get; set; }
|
|
public bool Pinned { get; set; }
|
|
public int Shots { get; set; }
|
|
public bool IsActiveScenario { get; set; }
|
|
public bool ShowAvgTotals { get; set; }
|
|
public bool IsUOMHours { get; set; }
|
|
public bool ShowActuals { get; set; }
|
|
public bool IsTableModeQuantity { get; set; }
|
|
public bool IsViewModeMonth { get; set; }
|
|
public bool ShowFilters { get; set; }
|
|
public string DataSection
|
|
{
|
|
get { return "scenarioCalendar"; }
|
|
}
|
|
public List<ExpenditureModel> AvailableExpenditures { get; set; } = new List<ExpenditureModel>();
|
|
public List<TeamInScenarioModel> TeamsInScenario { get; set; } = new List<TeamInScenarioModel>();
|
|
public bool NeedToRecalculateScenarioDetails { get; set; }
|
|
public bool NeedToAdjustMargin { get; set; }
|
|
|
|
/// <summary>
|
|
/// Rebuild calendar only by request
|
|
/// </summary>
|
|
public bool InitOnDemand { get; set; }
|
|
public string PagePreferences { get; set; }
|
|
public ScenarioCalendarOpener Opener { get; set; }
|
|
public bool IsBottomUp { get; set; }
|
|
public DateTime? ProjectDeadline { get; set; }
|
|
public bool ProjectHasDependencies { get; set; }
|
|
public DateTime? StartDateConstraint { get; set; }
|
|
public DateTime? EndDateConstraint { get; set; }
|
|
public long? StartDateConstraintMs
|
|
{
|
|
get
|
|
{
|
|
return StartDateConstraint.HasValue ? Utils.ConvertToUnixDate(StartDateConstraint.Value.ToUniversalTime()) : (long?)null;
|
|
}
|
|
}
|
|
public long? EndDateConstraintMs
|
|
{
|
|
get
|
|
{
|
|
return EndDateConstraint.HasValue ? Utils.ConvertToUnixDate(EndDateConstraint.Value.ToUniversalTime()) : (long?)null;
|
|
}
|
|
}
|
|
public ProjectDependencyListModel DependencyListModel { get; set; }
|
|
public DateTime? EndDateConstrantWithDeadline
|
|
{
|
|
get
|
|
{
|
|
if (EndDateConstraint.HasValue && ProjectDeadline.HasValue)
|
|
{
|
|
//deadline date comes before end date from dependancy
|
|
if ((EndDateConstraint.Value - ProjectDeadline.Value).TotalDays > 0)
|
|
return ProjectDeadline;
|
|
//deadline date comes after end date from dependancy
|
|
if ((EndDateConstraint.Value - ProjectDeadline.Value).TotalDays < 0)
|
|
return EndDateConstraint;
|
|
//both dates are the same
|
|
if ((EndDateConstraint.Value - ProjectDeadline.Value).TotalDays == 0)
|
|
return EndDateConstraint;
|
|
}
|
|
else if (ProjectDeadline.HasValue)
|
|
return ProjectDeadline;
|
|
else if (EndDateConstraint.HasValue)
|
|
return EndDateConstraint;
|
|
return null;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Enums
|
|
|
|
public enum ScenarioCalendarOpener
|
|
{
|
|
CreateScenarioWizard = 0,
|
|
Details = 1,
|
|
RMO = 2
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
public class ScenarioFinInfoModel
|
|
{
|
|
[DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
|
|
[Display(Name = "Date for start of change")]
|
|
[DateForStartOfChangeValidator]
|
|
public DateTime? DateForStartOfChanges { get; set; }
|
|
|
|
public bool IsRevenueGenerating { get; set; }
|
|
|
|
[Display(Name = "Projected Revenue")]
|
|
[DataType(DataType.Currency), DisplayFormat(DataFormatString = "{0:G29}", ApplyFormatInEditMode = true)]
|
|
public decimal? ProjectedRevenue { get; set; }
|
|
|
|
[Display(Name = "Calculated Revenue After Cost")]
|
|
public decimal RevenueAfterCost { get; set; }
|
|
|
|
[Display(Name = "Actual Revenue After Cost")]
|
|
public decimal? ActualRevenueAfterCost { get; set; }
|
|
|
|
[Display(Name = "Projected Margin")]
|
|
[Range(1, 100)]
|
|
[EitherOfRequired("FinInfo_ProjectedRevenue", "Either Projected Revenue or Margin should be entered", "", true)]
|
|
public int? GrossMargin { get; set; }
|
|
|
|
[Display(Name = "L&M Margin")]
|
|
[Range(1, 100)]
|
|
[EitherOfRequired("FinInfo_ProjectedRevenue", "Either Projected Revenue or Margin should be entered", "", true)]
|
|
public int? LMMargin { get; set; }
|
|
|
|
[Display(Name = "Use L&M Margin?")]
|
|
public bool UseLMMargin { get; set; }
|
|
|
|
[Display(Name = "Calculated Gross Margin (Forecast)")]
|
|
public int CalculatedGrossMargin { get; set; }
|
|
|
|
[Display(Name = "Calculated Gross Margin LM (Forecast)")]
|
|
public int CalculatedGrossMarginLM { get; set; }
|
|
|
|
[Display(Name = "Calculated Gross Margin (Actuals)")]
|
|
public int? CalculatedGrossMarginActuals { get; set; }
|
|
|
|
[Display(Name = "Calculated Gross Margin LM (Actuals)")]
|
|
public int? CalculatedGrossMarginLMActuals { get; set; }
|
|
|
|
[Display(Name = "Top-Down Expense")]
|
|
[TDDirectCostValidator]
|
|
public decimal TDDirectCosts { get; set; }
|
|
|
|
[Display(Name = "Bottom-Up Expense")]
|
|
public decimal BUDirectCosts { get; set; }
|
|
|
|
[Display(Name = "Actual Labor")]
|
|
public decimal? ActualLabor { get; set; }
|
|
|
|
[Display(Name = "Labor/Materials Split")]
|
|
public string LaborMaterialsSplit { get; set; }
|
|
|
|
[Display(Name = "Actual Labor/Materials Split")]
|
|
public string ActualLaborMaterialsSplit { get; set; }
|
|
|
|
[Display(Name = "Actual Materials")]
|
|
public decimal? ActualMaterials { get; set; }
|
|
public decimal ActualsTotal { get; set; }
|
|
public decimal EFXSplit { get; set; }
|
|
public short LaborSplitPercentage { get; set; }
|
|
public CostSavingModel CostSaving { get; set; }
|
|
|
|
#region Constructors
|
|
|
|
public ScenarioFinInfoModel()
|
|
{
|
|
CostSaving = new CostSavingModel();
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
public class ScenarioDetailsListItem
|
|
{
|
|
public Guid Id { get; set; }
|
|
public Guid ParentId { get; set; }
|
|
public Guid ExpenditureCategoryId { get; set; }
|
|
public DateTime? WeekEndingDate { get; set; }
|
|
public decimal Quantity { get; set; }
|
|
public int WeekOrdinal { get; set; }
|
|
public decimal DetailCost { get; set; }
|
|
public string ExpenditureCategoryName { get; set; }
|
|
public Guid? GlId { get; set; }
|
|
public Guid? UOMId { get; set; }
|
|
public Guid? CreditId { get; set; }
|
|
public ExpenditureCategoryModel.CategoryTypes CategoryType { get; set; }
|
|
public ExpenditureCategoryModel.UseTypes UseType { get; set; }
|
|
public ExpenditureCategoryModel.CgEfx CG_EFX { get; set; }
|
|
public Guid? SysField1 { get; set; }
|
|
public Guid SysField2 { get; set; }
|
|
public int? SortOrder { get; set; }
|
|
public bool ExpenditureCatagoryAllowsResource { get; set; }
|
|
}
|
|
|
|
public class ScenarioTeamInfoModel
|
|
{
|
|
public Guid Id { get; set; }
|
|
public string Name { get; set; }
|
|
public int Allocation { get; set; }
|
|
public bool CanBeDeleted { get; set; }
|
|
public Guid? PlannedCapacityScenarioId { get; set; }
|
|
public ICollection<PeopleResourceModel> Resources { get; set; }
|
|
public bool IsAccessible { get; set; }
|
|
|
|
public ScenarioTeamInfoModel()
|
|
{
|
|
Resources = new List<PeopleResourceModel>();
|
|
}
|
|
}
|
|
} |