2223 lines
103 KiB
C#
2223 lines
103 KiB
C#
using System.Collections.Specialized;
|
|
using System.Data.Entity;
|
|
using System.Data.Entity.Infrastructure;
|
|
using System.Net;
|
|
using System.Web.Routing;
|
|
using EnVisage.App_Start;
|
|
using EnVisage.Code.BLL;
|
|
using EnVisage.Code.Cache;
|
|
using EnVisage.Code.HtmlHelpers;
|
|
using EnVisage.Models;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Web.Mvc;
|
|
using jQuery.DataTables.Mvc;
|
|
using EnVisage.Code;
|
|
using Microsoft.AspNet.Identity;
|
|
|
|
namespace EnVisage.Controllers
|
|
{
|
|
[Authorize]
|
|
public class ScenariosController : BaseController
|
|
{
|
|
// GET: /Scenarios/Templates
|
|
[HttpGet]
|
|
[AreaSecurityAttribute(area = Areas.ScenarioTemplates, level = AccessLevel.Read)]
|
|
public ActionResult Templates()
|
|
{
|
|
if (!HtmlHelpers.CheckSecurityObjectPermission(null, Areas.ScenarioTemplates, AccessLevel.Read))
|
|
return Redirect("/");
|
|
return View();
|
|
}
|
|
|
|
[HttpGet]
|
|
//[ValidateAntiForgeryToken]
|
|
[AreaSecurityAttribute(area = Areas.Scenarios, level = AccessLevel.Write)]
|
|
public ActionResult LoadScenario(Guid? Id)
|
|
{
|
|
//if (Id.HasValue)
|
|
{
|
|
CreateScenarioModel model = new CreateScenarioModel();
|
|
model.ScenarioId = Guid.Empty;
|
|
model.TemplateId = Guid.Empty;
|
|
|
|
model.Project = DbContext.Projects.AsNoTracking().FirstOrDefault(p => p.Id == Id);
|
|
model.ProjectDeadline = model.Project.Deadline;
|
|
var TeamAllocations = model.Project.Team2Project.ToDictionary(c => c.TeamId, c => (double)100 / model.Project.Team2Project.Count());
|
|
model.TeamAllocations = Newtonsoft.Json.JsonConvert.SerializeObject(TeamAllocations);
|
|
if (model.Project.ParentProjectId.HasValue)
|
|
{
|
|
model.ProjectId = model.Project.ParentProjectId.Value;
|
|
model.PartId = Id;
|
|
}
|
|
else
|
|
{
|
|
model.ProjectId = Id.Value;
|
|
}
|
|
return PartialView("_createScenario", model);
|
|
}
|
|
|
|
}
|
|
|
|
[HttpPost]
|
|
[AreaSecurityAttribute(area = Areas.Scenarios, level = AccessLevel.Write)]
|
|
public JsonResult UpdateTeamsAllocation(ScenarioDetailModel model)
|
|
{
|
|
var projman = new ProjectManager(DbContext);
|
|
var project = projman.Load(model.ParentId);
|
|
var ProjTeamIds = project.Team2Project.Select(x => x.TeamId).ToList();
|
|
var teamallocations = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<Guid, short>>(model.TeamAllocationsJson);
|
|
var MissingTeams = teamallocations.Keys.Where(x => !ProjTeamIds.Contains(x)).ToList();
|
|
var OtherScenarios = project.Scenarios.ToList();
|
|
DbContext.Team2Scenario.RemoveRange(DbContext.Team2Scenario.Where(x => x.ScenarioId == model.Id).ToList());
|
|
DbContext.SaveChanges();
|
|
foreach (var teamalloc in teamallocations)
|
|
{
|
|
var newTA = new Team2Scenario();
|
|
newTA.Id = Guid.NewGuid();
|
|
newTA.ScenarioId = model.Id;
|
|
newTA.TeamId = teamalloc.Key;
|
|
newTA.Allocation = teamalloc.Value;
|
|
DbContext.Team2Scenario.Add(newTA);
|
|
}
|
|
foreach (var team in MissingTeams)
|
|
{
|
|
var newTP = new Team2Project();
|
|
newTP.Id = Guid.NewGuid();
|
|
newTP.ProjectId = model.ParentId;
|
|
newTP.TeamId = team;
|
|
DbContext.Team2Project.Add(newTP);
|
|
foreach (var scen in OtherScenarios)
|
|
{
|
|
if (scen.Id == model.Id)
|
|
continue;
|
|
var newTA = new Team2Scenario();
|
|
newTA.Id = Guid.NewGuid();
|
|
newTA.ScenarioId = scen.Id;
|
|
newTA.TeamId = team;
|
|
newTA.Allocation = 0;
|
|
DbContext.Team2Scenario.Add(newTA);
|
|
}
|
|
}
|
|
DbContext.SaveChanges();
|
|
return Json("ok", JsonRequestBehavior.AllowGet);
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
[AreaSecurityAttribute(area = Areas.Scenarios, level = AccessLevel.Write)]
|
|
public ActionResult CreateScenario(CreateScenarioModel model, Guid[] expCatId, string[] expCatName,
|
|
string[] expCatGroup, bool[] expCatChecked)
|
|
{
|
|
//if (model == null || ContentLocker.IsLock("Trainings", model.Id.ToString(), User.Identity.Name))
|
|
// return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
|
|
try
|
|
{
|
|
model.TrimStringProperties();
|
|
var costSavingItems = string.IsNullOrEmpty(model.CostSavingItems)
|
|
? new List<ScenarioCostSavingModel>()
|
|
: Newtonsoft.Json.JsonConvert.DeserializeObject<List<ScenarioCostSavingModel>>
|
|
(model.CostSavingItems) ?? new List<ScenarioCostSavingModel>();
|
|
if (ModelState.IsValid)
|
|
{
|
|
var projman = new ProjectManager(DbContext);
|
|
var project = projman.Load(model.PartId ?? model.ProjectId);
|
|
model.IsRevenueGenerating = project.IsRevenueGenerating;
|
|
model.Project = project;
|
|
if (expCatId != null && expCatName != null && expCatGroup != null && expCatChecked != null &&
|
|
expCatId.Length == expCatName.Length && expCatId.Length == expCatGroup.Length &&
|
|
expCatId.Length == expCatChecked.Length)
|
|
{
|
|
model.ScenarioExpenditures = new ScenarioModel.ExpenditureItem[expCatId.Length];
|
|
for (var i = 0; i < expCatId.Length; i++)
|
|
{
|
|
model.ScenarioExpenditures[i] = new ScenarioModel.ExpenditureItem
|
|
{
|
|
Id = expCatId[i],
|
|
Group = expCatGroup[i],
|
|
Name = expCatName[i],
|
|
Checked = expCatChecked[i]
|
|
};
|
|
}
|
|
}
|
|
model.ProjectDeadline = project.Deadline;
|
|
var ProjTeamIds = model.Project.Team2Project.Select(x => x.TeamId).ToList();
|
|
var teamallocations =
|
|
Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<Guid, short>>(model.TeamAllocations);
|
|
var MissingTeams = teamallocations.Keys.Where(x => !ProjTeamIds.Contains(x)).ToList();
|
|
var OtherScenarios = model.Project.Scenarios.ToList();
|
|
var manager = new ScenarioManager(DbContext);
|
|
var dbObj = manager.Save((ScenarioModel) model);
|
|
if (!model.SaveAsDraft)
|
|
{
|
|
foreach (var teamalloc in teamallocations)
|
|
{
|
|
var newTA = new Team2Scenario();
|
|
newTA.Id = Guid.NewGuid();
|
|
newTA.ScenarioId = dbObj.Id;
|
|
newTA.TeamId = teamalloc.Key;
|
|
newTA.Allocation = teamalloc.Value;
|
|
DbContext.Team2Scenario.Add(newTA);
|
|
}
|
|
foreach (var team in MissingTeams)
|
|
{
|
|
var newTP = new Team2Project();
|
|
newTP.Id = Guid.NewGuid();
|
|
newTP.ProjectId = model.ProjectId;
|
|
newTP.TeamId = team;
|
|
DbContext.Team2Project.Add(newTP);
|
|
foreach (var scen in OtherScenarios)
|
|
{
|
|
if (scen.Id == dbObj.Id)
|
|
continue;
|
|
var newTA = new Team2Scenario();
|
|
newTA.Id = Guid.NewGuid();
|
|
newTA.ScenarioId = scen.Id;
|
|
newTA.TeamId = team;
|
|
newTA.Allocation = 0;
|
|
DbContext.Team2Scenario.Add(newTA);
|
|
}
|
|
}
|
|
foreach (var scenarioCostSavingModel in costSavingItems)
|
|
{
|
|
for (var month = 1; month < scenarioCostSavingModel.Costs.Length; month++)
|
|
{
|
|
if (scenarioCostSavingModel.Costs[month].HasValue)
|
|
DbContext.CostSavings.Add(new CostSaving
|
|
{
|
|
Id = Guid.NewGuid(),
|
|
Cost = scenarioCostSavingModel.Costs[month].Value,
|
|
Month = (short) month,
|
|
Year = scenarioCostSavingModel.Year,
|
|
ScenarioId = dbObj.Id
|
|
});
|
|
}
|
|
}
|
|
DbContext.SaveChanges();
|
|
}
|
|
|
|
//ContentLocker.RemoveLock("Trainings", model.Id.ToString(), User.Identity.Name);
|
|
model.Project = DbContext.Projects.AsNoTracking().FirstOrDefault(p => p.Id == model.ProjectId);
|
|
return new HttpStatusCodeResult(HttpStatusCode.OK); //PartialView("_createScenario", model);
|
|
}
|
|
}
|
|
catch (BLLException blEx) // handle any system specific error
|
|
{
|
|
// display error message if required
|
|
if (blEx.DisplayError)
|
|
ModelState.AddModelError(string.Empty, blEx.Message);
|
|
else // if display not requried then display modal form with general error message
|
|
{
|
|
LogException(blEx);
|
|
//SetErrorScript();
|
|
ModelState.AddModelError(string.Empty, "Cannot save expenditure categoies. Try again later.");
|
|
}
|
|
}
|
|
catch (Exception exception) // handle any unexpected error
|
|
{
|
|
LogException(exception);
|
|
//SetErrorScript();
|
|
ModelState.AddModelError(string.Empty, "Cannot save expenditure categoies. Try again later.");
|
|
}
|
|
|
|
HttpContext.Response.StatusCode = 500;
|
|
HttpContext.Response.Clear();
|
|
//return Redirect(HttpContext.Request.UrlReferrer.AbsoluteUri);
|
|
model.Project = DbContext.Projects.AsNoTracking().FirstOrDefault(p => p.Id == model.ProjectId);
|
|
return PartialView("_createScenario", model);
|
|
}
|
|
|
|
[HttpGet]
|
|
//[ValidateAntiForgeryToken]
|
|
[AreaSecurityAttribute(area = Areas.Trainings, level = AccessLevel.Write)]
|
|
public ActionResult GetECsByTemplateId(Guid? Id)
|
|
{
|
|
var manager = new ScenarioManager(DbContext);
|
|
var ec = manager.GetExpenditureCategories(Id);
|
|
return PartialView("_createScenarioExpenditures", ec);
|
|
}
|
|
|
|
[HttpGet]
|
|
//[ValidateAntiForgeryToken]
|
|
[AreaSecurityAttribute(area = Areas.Trainings, level = AccessLevel.Write)]
|
|
public ActionResult GetProjectPartsByProjectId(Guid? Id)
|
|
{
|
|
var pp = Utils.GetProjectParts(Id);
|
|
return PartialView("_createScenarioProjectParts", pp);
|
|
}
|
|
|
|
[HttpPost]
|
|
[AreaSecurityAttribute(area = Areas.Scenarios, level = AccessLevel.Write)]
|
|
public ActionResult ProcessRates(RatesModel model)
|
|
{
|
|
try
|
|
{
|
|
model.TrimStringProperties();
|
|
switch (model.Mode)
|
|
{
|
|
case RatesModel.FormMode.ListRates:
|
|
|
|
#region List Rates
|
|
|
|
model.EditRateId = Guid.Empty;
|
|
model.DeleteRateId = Guid.Empty;
|
|
if (!Guid.Empty.Equals(model.ExpenditureCategoryId))
|
|
{
|
|
var gRates = (from c in DbContext.Rates
|
|
where
|
|
c.ExpenditureCategoryId == model.ExpenditureCategoryId &&
|
|
c.Type == (int) RateModel.RateType.Global
|
|
select c);
|
|
model.AddGlobalRange(gRates.ToList());
|
|
}
|
|
if (Guid.Empty != model.ScenarioId && !Guid.Empty.Equals(model.ExpenditureCategoryId))
|
|
{
|
|
var lRates = (from c in DbContext.Rates
|
|
where
|
|
c.ExpenditureCategoryId == model.ExpenditureCategoryId &&
|
|
c.Type == (int) RateModel.RateType.Derived &&
|
|
c.ParentId == model.ScenarioId
|
|
select c);
|
|
model.AddLocalRange(lRates.ToList());
|
|
}
|
|
|
|
#endregion
|
|
|
|
break;
|
|
case RatesModel.FormMode.EditRate:
|
|
|
|
#region Load Edit Rate Form
|
|
|
|
if (model.EditRateId.HasValue && !Guid.Empty.Equals(model.EditRateId))
|
|
{
|
|
var rate = DbContext.Rates.AsNoTracking().FirstOrDefault(t => t.Id == model.EditRateId);
|
|
if (rate != null)
|
|
{
|
|
model.EditRate = new RateModel()
|
|
{
|
|
Id = rate.Id,
|
|
DerivedObjectId = rate.DerivedId,
|
|
EndDate = rate.EndDate,
|
|
ExpenditureCategoryId = rate.ExpenditureCategoryId,
|
|
FreezeRate = rate.FreezeRate,
|
|
ParentId = rate.ParentId,
|
|
Rate1 = rate.Rate1,
|
|
StartDate = rate.StartDate,
|
|
Type = (RateModel.RateType) rate.Type
|
|
};
|
|
}
|
|
}
|
|
else
|
|
{
|
|
model.EditRate = new RateModel()
|
|
{
|
|
DerivedObjectId = Guid.Empty,
|
|
EndDate = new DateTime(9999, 12, 31),
|
|
ExpenditureCategoryId = model.ExpenditureCategoryId,
|
|
FreezeRate = 0,
|
|
ParentId = model.ScenarioId,
|
|
Rate1 = 0,
|
|
StartDate = new DateTime(1753, 1, 1),
|
|
Type = RateModel.RateType.Derived
|
|
};
|
|
}
|
|
|
|
#endregion
|
|
|
|
break;
|
|
case RatesModel.FormMode.ConfirmEditRate:
|
|
|
|
#region Save Rate
|
|
|
|
if (ModelState.IsValid)
|
|
{
|
|
if (ContentLocker.IsLock("ExpenditureCategoryRate", model.EditRateId.ToString(),
|
|
User.Identity.Name))
|
|
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
|
|
var manager = new RateManager(DbContext);
|
|
manager.Save(model.EditRate);
|
|
DbContext.SaveChanges();
|
|
manager.Dispose();
|
|
ContentLocker.RemoveLock("ExpenditureCategoryRate", model.EditRateId.ToString(),
|
|
User.Identity.Name);
|
|
model.Mode = RatesModel.FormMode.ListRates; // reset action mode
|
|
model.EditRateId = Guid.Empty;
|
|
model.DeleteRateId = Guid.Empty;
|
|
if (!Guid.Empty.Equals(model.ExpenditureCategoryId))
|
|
{
|
|
var gRates = (from c in DbContext.Rates
|
|
where
|
|
c.ExpenditureCategoryId == model.ExpenditureCategoryId &&
|
|
c.Type == (int) RateModel.RateType.Global
|
|
select c);
|
|
model.AddGlobalRange(gRates.ToList());
|
|
}
|
|
if (Guid.Empty != model.ScenarioId && !Guid.Empty.Equals(model.ExpenditureCategoryId))
|
|
{
|
|
var lRates = (from c in DbContext.Rates
|
|
where
|
|
c.ExpenditureCategoryId == model.ExpenditureCategoryId &&
|
|
c.Type == (int) RateModel.RateType.Derived &&
|
|
c.ParentId == model.ScenarioId
|
|
select c);
|
|
model.AddLocalRange(lRates.ToList());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
model.Mode = RatesModel.FormMode.EditRate;
|
|
HttpContext.Response.StatusCode = 500;
|
|
HttpContext.Response.Clear();
|
|
}
|
|
|
|
#endregion
|
|
|
|
break;
|
|
case RatesModel.FormMode.DeriveRate:
|
|
|
|
#region Derive rate from global
|
|
var sManager = new ScenarioManager(DbContext);
|
|
var scenario = sManager.Load(model.ScenarioId);
|
|
if (!Guid.Empty.Equals(model.ExpenditureCategoryId) && !Guid.Empty.Equals(model.ScenarioId))
|
|
{
|
|
var rates = (from c in DbContext.Rates
|
|
where
|
|
c.ExpenditureCategoryId == model.ExpenditureCategoryId &&
|
|
c.Type == (int) RateModel.RateType.Global &&
|
|
c.StartDate <= scenario.EndDate &&
|
|
c.EndDate >= scenario.StartDate
|
|
select c).ToList();
|
|
foreach (var rate in rates)
|
|
{
|
|
var derivedrates = (from c in DbContext.Rates
|
|
where
|
|
c.ExpenditureCategoryId == model.ExpenditureCategoryId &&
|
|
c.ParentId == model.ScenarioId && c.DerivedId == rate.Id
|
|
select c).ToList();
|
|
DbContext.Rates.RemoveRange(derivedrates);
|
|
var newrate = new Rate
|
|
{
|
|
Id = Guid.NewGuid(),
|
|
Rate1 = rate.Rate1,
|
|
StartDate = (rate.StartDate < scenario.StartDate) ? scenario.StartDate.Value : rate.StartDate,
|
|
EndDate = (rate.EndDate > scenario.EndDate) ? scenario.EndDate.Value : rate.EndDate,
|
|
ExpenditureCategoryId = rate.ExpenditureCategoryId,
|
|
FreezeRate = rate.FreezeRate,
|
|
ParentId = model.ScenarioId,
|
|
Type = (short) RateModel.RateType.Derived,
|
|
DerivedId = rate.Id
|
|
};
|
|
DbContext.Rates.Add(newrate);
|
|
DbContext.SaveChanges();
|
|
}
|
|
}
|
|
model.Mode = RatesModel.FormMode.ListRates; // reset action mode
|
|
model.EditRateId = Guid.Empty;
|
|
model.DeleteRateId = Guid.Empty;
|
|
if (!Guid.Empty.Equals(model.ExpenditureCategoryId))
|
|
{
|
|
var gRates = (from c in DbContext.Rates
|
|
where
|
|
c.ExpenditureCategoryId == model.ExpenditureCategoryId &&
|
|
c.Type == (int) RateModel.RateType.Global
|
|
select c);
|
|
model.AddGlobalRange(gRates.ToList());
|
|
}
|
|
if (Guid.Empty != model.ScenarioId && !Guid.Empty.Equals(model.ExpenditureCategoryId))
|
|
{
|
|
var lRates = (from c in DbContext.Rates
|
|
where
|
|
c.ExpenditureCategoryId == model.ExpenditureCategoryId &&
|
|
c.Type == (int) RateModel.RateType.Derived &&
|
|
c.ParentId == model.ScenarioId
|
|
select c);
|
|
model.AddLocalRange(lRates.ToList());
|
|
}
|
|
|
|
#endregion
|
|
|
|
break;
|
|
case RatesModel.FormMode.ConfirmDeleteRate:
|
|
|
|
#region delete rate
|
|
|
|
if (!Guid.Empty.Equals(model.ExpenditureCategoryId) && !Guid.Empty.Equals(model.ScenarioId))
|
|
{
|
|
var deleterates = (from c in DbContext.Rates
|
|
where
|
|
c.ExpenditureCategoryId == model.ExpenditureCategoryId &&
|
|
c.ParentId == model.ScenarioId
|
|
select c);
|
|
if (model.DeleteRateId != null && !Guid.Empty.Equals(model.DeleteRateId))
|
|
deleterates = deleterates.Where(t => t.Id == model.DeleteRateId);
|
|
DbContext.Rates.RemoveRange(deleterates);
|
|
DbContext.SaveChanges();
|
|
}
|
|
model.DeleteRateId = Guid.Empty;
|
|
model.EditRateId = Guid.Empty;
|
|
model.Mode = RatesModel.FormMode.ListRates; // reset action mode
|
|
if (!Guid.Empty.Equals(model.ExpenditureCategoryId))
|
|
{
|
|
var gRates = (from c in DbContext.Rates
|
|
where
|
|
c.ExpenditureCategoryId == model.ExpenditureCategoryId &&
|
|
c.Type == (int) RateModel.RateType.Global
|
|
select c);
|
|
model.AddGlobalRange(gRates.ToList());
|
|
}
|
|
if (Guid.Empty != model.ScenarioId && !Guid.Empty.Equals(model.ExpenditureCategoryId))
|
|
{
|
|
var lRates = (from c in DbContext.Rates
|
|
where
|
|
c.ExpenditureCategoryId == model.ExpenditureCategoryId &&
|
|
c.Type == (int) RateModel.RateType.Derived &&
|
|
c.ParentId == model.ScenarioId
|
|
select c);
|
|
model.AddLocalRange(lRates.ToList());
|
|
}
|
|
break;
|
|
|
|
#endregion
|
|
}
|
|
return PartialView("_rates", model);
|
|
}
|
|
catch (BLLException blEx)
|
|
{
|
|
if (blEx.DisplayError)
|
|
SetErrorScript(message: blEx.Message);
|
|
else
|
|
{
|
|
LogException(blEx);
|
|
SetErrorScript();
|
|
}
|
|
model.Mode = RatesModel.FormMode.EditRate;
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
LogException(exception);
|
|
SetErrorScript();
|
|
model.Mode = RatesModel.FormMode.EditRate;
|
|
}
|
|
if (ModelState.IsValid && (RatesModel.FormMode.ConfirmEditRate == model.Mode || RatesModel.FormMode.ConfirmDeleteRate == model.Mode) && Guid.Empty != model.EditRateId)
|
|
ContentLocker.RemoveLock("ExpenditureCategoryRate", model.EditRateId.ToString(), User.Identity.Name);
|
|
HttpContext.Response.StatusCode = 500;
|
|
HttpContext.Response.Clear();
|
|
return PartialView("_rates", model);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns JSON UnitOfMeasure list with filters and sort for jQuery DataTables
|
|
/// </summary>
|
|
[HttpPost]
|
|
[AreaSecurityAttribute(area = Areas.ScenarioTemplates, level = AccessLevel.Read)]
|
|
public JsonResult Templates(JQueryDataTablesModel jQueryDataTablesModel)
|
|
{
|
|
int totalRecordCount;
|
|
int searchRecordCount;
|
|
|
|
var units = GetTemplates(startIndex: jQueryDataTablesModel.iDisplayStart,
|
|
pageSize: jQueryDataTablesModel.iDisplayLength, sortedColumns: jQueryDataTablesModel.GetSortedColumns(),
|
|
totalRecordCount: out totalRecordCount, searchRecordCount: out searchRecordCount, searchString: jQueryDataTablesModel.sSearch);
|
|
|
|
return this.DataTablesJson(items: units,
|
|
totalRecords: totalRecordCount,
|
|
totalDisplayRecords: searchRecordCount,
|
|
sEcho: jQueryDataTablesModel.sEcho);
|
|
|
|
}
|
|
|
|
private IEnumerable<ScenarioListItemModel> GetTemplates(int startIndex,
|
|
int pageSize,
|
|
IEnumerable<SortedColumn> sortedColumns,
|
|
out int totalRecordCount,
|
|
out int searchRecordCount,
|
|
string searchString)
|
|
{
|
|
var query = from c in DbContext.Scenarios where c.Type == (int)ScenarioType.Template select new ScenarioListItemModel
|
|
{ Id = c.Id, Name = c.Name,
|
|
StartDate = c.StartDate, EndDate = c.EndDate, Duration = c.Duration, CGSplit = c.CGSplit, EFXSplit = c.EFXSplit, ScenariosCount = c.ChildScenarios.Count()};
|
|
|
|
//filter
|
|
if (!string.IsNullOrWhiteSpace(searchString))
|
|
{
|
|
query = query.Where(c => c.Name.ToLower().Contains(searchString.ToLower()));
|
|
}
|
|
|
|
//sort
|
|
foreach (var sortedColumn in sortedColumns)
|
|
{
|
|
switch (sortedColumn.PropertyName)
|
|
{
|
|
case "Id":
|
|
if (sortedColumn.Direction == SortingDirection.Ascending)
|
|
query = query.OrderBy(c => c.Id);
|
|
else
|
|
query = query.OrderByDescending(c => c.Id);
|
|
break;
|
|
case "StartDate":
|
|
if (sortedColumn.Direction == SortingDirection.Ascending)
|
|
query = query.OrderBy(c => c.StartDate);
|
|
else
|
|
query = query.OrderByDescending(c => c.StartDate);
|
|
break;
|
|
case "EndDate":
|
|
if (sortedColumn.Direction == SortingDirection.Ascending)
|
|
query = query.OrderBy(c => c.EndDate);
|
|
else
|
|
query = query.OrderByDescending(c => c.EndDate);
|
|
break;
|
|
case "Duration":
|
|
if (sortedColumn.Direction == SortingDirection.Ascending)
|
|
query = query.OrderBy(c => c.Duration);
|
|
else
|
|
query = query.OrderByDescending(c => c.Duration);
|
|
break;
|
|
case "CGSplit":
|
|
if (sortedColumn.Direction == SortingDirection.Ascending)
|
|
query = query.OrderBy(c => c.CGSplit);
|
|
else
|
|
query = query.OrderByDescending(c => c.CGSplit);
|
|
break;
|
|
case "EFXSplit":
|
|
if (sortedColumn.Direction == SortingDirection.Ascending)
|
|
query = query.OrderBy(c => c.EFXSplit);
|
|
else
|
|
query = query.OrderByDescending(c => c.EFXSplit);
|
|
break;
|
|
case "ScenariosCount":
|
|
if (sortedColumn.Direction == SortingDirection.Ascending)
|
|
query = query.OrderBy(c => c.ScenariosCount);
|
|
else
|
|
query = query.OrderByDescending(c => c.ScenariosCount);
|
|
break;
|
|
default:
|
|
if (sortedColumn.Direction == SortingDirection.Ascending)
|
|
query = query.OrderBy(c => c.Name);
|
|
else
|
|
query = query.OrderByDescending(c => c.Name);
|
|
break;
|
|
}
|
|
}
|
|
|
|
totalRecordCount = DbContext.Scenarios.Count(s => s.Type == (int?)ScenarioType.Template);
|
|
searchRecordCount = query.Count();
|
|
return query.Skip(startIndex).Take(pageSize).ToList();
|
|
}
|
|
|
|
// GET: /Scenarios/
|
|
[HttpGet]
|
|
[AreaSecurityAttribute(area = Areas.Scenarios, level = AccessLevel.Read)]
|
|
public ActionResult Index()
|
|
{
|
|
return View();
|
|
}
|
|
|
|
// GET: /Scenarios/
|
|
[HttpGet]
|
|
public ActionResult LoadExpenditures(Guid? id)
|
|
{
|
|
if (id == null || id == Guid.Empty)
|
|
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
|
|
try
|
|
{
|
|
var manager = new ScenarioManager(DbContext);
|
|
var model = manager.GetExpenditureCategories(id.Value);
|
|
return PartialView("_expenditures", model);
|
|
}
|
|
catch (BLLException blEx)
|
|
{
|
|
if (blEx.DisplayError)
|
|
SetErrorScript(message: blEx.Message);
|
|
else
|
|
{
|
|
LogException(blEx);
|
|
SetErrorScript();
|
|
}
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
LogException(exception);
|
|
SetErrorScript();
|
|
}
|
|
return PartialView("_expenditures", new List<ScenarioModel.ExpenditureItem>());
|
|
}
|
|
|
|
// GET: /Scenarios/Edit/5
|
|
[HttpGet]
|
|
[AreaSecurityAttribute(area = Areas.Scenarios, level = AccessLevel.Write)]
|
|
public ActionResult Edit(Guid? id, Guid? parentId, string backUrl, string backName)
|
|
{
|
|
if ((id == null || id == Guid.Empty) && (parentId == null || parentId == Guid.Empty))
|
|
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
var model = new ScenarioModel();
|
|
try
|
|
{
|
|
var manager = new ScenarioManager(DbContext);
|
|
model = (ScenarioModel)manager.Load(id) ?? new ScenarioModel();
|
|
if (model.Id == Guid.Empty) // create new scenario
|
|
{
|
|
model.LaborSplitPercentage = 100;
|
|
//model.StartDate = DateTime.Today;
|
|
//model.EndDate = DateTime.Today.AddYears(1);
|
|
//model.MilestoneStartDate = DateTime.Today;
|
|
model.UseActuals = true;
|
|
model.IsActiveScenario = true;
|
|
model.TotalMilestones = 1;
|
|
model.GrossMargin = 0;
|
|
model.LMMargin = 0;
|
|
|
|
var project = DbContext.Projects.FirstOrDefault(x => x.Id == parentId);
|
|
if (project != null)
|
|
{
|
|
model.IsRevenueGenerating = project.IsRevenueGenerating;
|
|
}
|
|
|
|
var initialTemplate = Utils.GetScenarioTemplates().FirstOrDefault();
|
|
if (initialTemplate != null)
|
|
{
|
|
var items = manager.GetExpenditureCategories(new Guid(initialTemplate.Value));
|
|
if (items != null)
|
|
model.Expenditures = items;
|
|
}
|
|
if (!model.IsRevenueGenerating)
|
|
{
|
|
model.ProjectedRevenue = 0;
|
|
}
|
|
}
|
|
else // edit scenario
|
|
{
|
|
model.PriorWeekCutOff = DateTime.Today;
|
|
if (!model.MilestoneStartDate.HasValue || model.MilestoneStartDate.Value == Constants.ProjectionsDefaultDate)
|
|
model.MilestoneStartDate = model.StartDate;
|
|
model.UseActuals = !model.GrowthScenario;
|
|
var items = manager.GetExpenditureCategories(model.Id);
|
|
if (items != null)
|
|
model.Expenditures = items;
|
|
}
|
|
if (model.UseLMMargin)
|
|
{
|
|
model.GrossMargin = null;
|
|
}
|
|
else
|
|
{
|
|
model.LMMargin = null;
|
|
}
|
|
if (model.Id == Guid.Empty && parentId != null)
|
|
model.ParentId = parentId.Value;
|
|
model.BackUrl = backUrl;
|
|
model.BackName = backName;
|
|
}
|
|
catch (BLLException blEx)
|
|
{
|
|
if (blEx.DisplayError)
|
|
SetErrorScript(message: blEx.Message);
|
|
else
|
|
{
|
|
LogException(blEx);
|
|
SetErrorScript();
|
|
}
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
LogException(exception);
|
|
SetErrorScript();
|
|
}
|
|
return View(model);
|
|
}
|
|
|
|
[HttpPost]
|
|
//[ValidateAntiForgeryToken]
|
|
[AreaSecurityAttribute(area = Areas.Scenarios, level = AccessLevel.Write)]
|
|
public ActionResult ChangeExpenditures(ScenarioDetailModel model, Guid[] expCatId, string[] expCatName, string[] expCatGroup, bool[] expCatChecked)
|
|
{
|
|
List<ExpenditureModel> expCatList = new List<ExpenditureModel>();
|
|
for (var i = 0; i < expCatId.Length; i++)
|
|
{
|
|
if (expCatChecked.Length > i && expCatChecked[i] && expCatName.Length > i)
|
|
{
|
|
expCatList.Add(new ExpenditureModel()
|
|
{
|
|
Id = expCatId[i],
|
|
Name = expCatName[i]
|
|
});
|
|
}
|
|
}
|
|
|
|
var manager = new ScenarioManager(DbContext);
|
|
ModelState.Clear();
|
|
if (model != null && model.Id != Guid.Empty)
|
|
{
|
|
try
|
|
{
|
|
manager.SaveExpenditureCategories(model.Id, expCatList);
|
|
return JavaScript("window.location.search += '&tab=scenarios';");
|
|
//return Redirect(HttpContext.Request.UrlReferrer.AbsoluteUri);
|
|
}
|
|
catch (BLLException blEx) // handle any system specific error
|
|
{
|
|
// display error message if required
|
|
if (blEx.DisplayError)
|
|
ModelState.AddModelError(string.Empty, blEx.Message);
|
|
else // if display not requried then display modal form with general error message
|
|
{
|
|
LogException(blEx);
|
|
//SetErrorScript();
|
|
ModelState.AddModelError(string.Empty, "Cannot save expedenture categoies. Try again later.");
|
|
}
|
|
}
|
|
catch (Exception exception) // handle any unexpected error
|
|
{
|
|
LogException(exception);
|
|
//SetErrorScript();
|
|
ModelState.AddModelError(string.Empty, "Cannot save expedenture categoies. Try again later.");
|
|
}
|
|
}
|
|
|
|
HttpContext.Response.StatusCode = 500;
|
|
HttpContext.Response.Clear();
|
|
model.ScenarioExpenditures = manager.GetExpenditureCategories(model.Id);
|
|
model.ScenarioExpenditures.Where(x => expCatList.Select(ec => ec.Id).Contains(x.Id)).ToList().ForEach(x => x.Checked = true);
|
|
return PartialView("_expendituresModal", model);
|
|
}
|
|
|
|
// POST: /Scenarios/Edit/5
|
|
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
|
|
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
[AreaSecurityAttribute(area = Areas.Scenarios, level = AccessLevel.Write)]
|
|
public ActionResult Edit(ScenarioModel model, Guid[] expCatId, string[] expCatName, string[] expCatGroup, bool[] expCatChecked)
|
|
{
|
|
if (model.Id != Guid.Empty && ContentLocker.IsLock("Scenario", model.Id.ToString(), User.Identity.Name))
|
|
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
//if (model.Id == Guid.Empty) model.Id = Guid.NewGuid();
|
|
model.TrimStringProperties();
|
|
|
|
if (!model.AsDraft && expCatChecked.All(c => c == false))
|
|
ModelState.AddModelError("ExpenditureCategoriesEmpty",string.Format(Constants.ERROR_ONE_OR_MORE_SELECTED_ELEMENTS_REQUIRED, "Expenditure Categories"));
|
|
|
|
if (expCatId != null && expCatName != null && expCatGroup != null && expCatChecked != null &&
|
|
expCatId.Length == expCatName.Length && expCatId.Length == expCatGroup.Length && expCatId.Length == expCatChecked.Length)
|
|
{
|
|
model.Expenditures = new ScenarioModel.ExpenditureItem[expCatId.Length];
|
|
for (var i = 0; i < expCatId.Length; i++)
|
|
{
|
|
model.Expenditures[i] = new ScenarioModel.ExpenditureItem
|
|
{
|
|
Id = expCatId[i],
|
|
Group = expCatGroup[i],
|
|
Name = expCatName[i],
|
|
Checked = expCatChecked[i]
|
|
};
|
|
}
|
|
}
|
|
|
|
if (ModelState.IsValid)
|
|
{
|
|
try
|
|
{
|
|
var manager = new ScenarioManager(DbContext);
|
|
var scenario = manager.Save(model);
|
|
if (model.Id != Guid.Empty)
|
|
ContentLocker.RemoveLock("Scenario", model.Id.ToString(), User.Identity.Name);
|
|
return RedirectToAction("Details", "Scenarios",
|
|
new {
|
|
id = scenario.Id,
|
|
backUrl = model.BackUrl,
|
|
backName = model.BackName
|
|
});
|
|
}
|
|
catch (BLLException blEx) // handle any system specific error
|
|
{
|
|
// display error message if required
|
|
if (blEx.DisplayError)
|
|
ModelState.AddModelError(string.Empty, blEx.Message);
|
|
else // if display not requried then display modal form with general error message
|
|
{
|
|
LogException(blEx);
|
|
SetErrorScript();
|
|
}
|
|
}
|
|
catch (Exception exception) // handle any unexpected error
|
|
{
|
|
LogException(exception);
|
|
SetErrorScript();
|
|
}
|
|
}
|
|
// return empty model with validation messages (if any)
|
|
string url = Request.QueryString["ref"];
|
|
if (!string.IsNullOrEmpty(url))
|
|
return Redirect(url);
|
|
return View(model);
|
|
}
|
|
|
|
[HttpPost]
|
|
public ActionResult LoadScenarioCalendar(ScenarioDetailsModel model, Guid[] expCatId, bool[] expCatChecked)
|
|
{
|
|
if (ModelState.IsValid)
|
|
{
|
|
try
|
|
{
|
|
model = GetScenarioCalendar(model);
|
|
return Json(model);
|
|
}
|
|
catch (BLLException blEx) // handle any system specific error
|
|
{
|
|
// display error message if required
|
|
if (blEx.DisplayError)
|
|
ModelState.AddModelError(string.Empty, blEx.Message);
|
|
else // if display not requried then display modal form with general error message
|
|
{
|
|
LogException(blEx);
|
|
SetErrorScript();
|
|
}
|
|
}
|
|
catch (Exception exception) // handle any unexpected error
|
|
{
|
|
LogException(exception);
|
|
SetErrorScript();
|
|
}
|
|
}
|
|
return PartialView("_scenarioCalendar", model);
|
|
}
|
|
|
|
[HttpPost]
|
|
public ActionResult LoadJsonScenarioCalendar(ScenarioDetailsModel model)
|
|
{
|
|
if (model == null || model.ScenarioId == Guid.Empty)
|
|
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
var scenario = DbContext.Scenarios.AsNoTracking().FirstOrDefault(t => t.Id == model.ScenarioId);
|
|
if (scenario == null)
|
|
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
|
|
model.StartDate = scenario.StartDate ?? DateTime.Today;
|
|
model.EndDate = scenario.EndDate ?? DateTime.Today.AddYears(1);
|
|
model.GrowthScenario = scenario.GrowthScenario;
|
|
model.ScenarioId = scenario.Id;
|
|
model.ParentId = scenario.ParentId ?? Guid.Empty;
|
|
model.ScenarioType = (ScenarioType?) scenario.Type;
|
|
return Json(GetScenarioCalendar(model), JsonRequestBehavior.AllowGet);
|
|
}
|
|
|
|
private class Pairs
|
|
{
|
|
public Guid Id { get; set; }
|
|
public decimal Quantity { get; set; }
|
|
}
|
|
private ScenarioDetailsModel GetScenarioCalendar(ScenarioDetailsModel model)
|
|
{
|
|
DateTime periodStartDate;
|
|
DateTime periodEndDate;
|
|
DateTime? actualsEndDate;
|
|
Guid actualScenarioId = Guid.Empty;
|
|
var allExpCats = DbContext.ExpenditureCategory.AsNoTracking().ToList();
|
|
var allUoms = DbContext.UOMs.AsNoTracking().ToList();
|
|
if (!model.IsUOMHours.HasValue)
|
|
{
|
|
var user = new UsersCache().Value.FirstOrDefault(x => x.Id == new Guid(HttpContext.User.Identity.GetUserId()));
|
|
if (user != null)
|
|
model.IsUOMHours = !user.PreferredResourceAllocation;
|
|
}
|
|
switch (model.ScenarioType)
|
|
{
|
|
case ScenarioType.LoanOut:
|
|
case ScenarioType.Training:
|
|
case ScenarioType.Vacation:
|
|
periodStartDate = new DateTime(DateTime.Today.Year, 1, 1);
|
|
periodEndDate = new DateTime(DateTime.Today.Year, 12, 31);
|
|
break;
|
|
case ScenarioType.Actuals:
|
|
periodStartDate = model.StartDate;
|
|
periodEndDate = model.EndDate;
|
|
break;
|
|
default:
|
|
periodStartDate = model.StartDate;
|
|
periodEndDate = model.EndDate;
|
|
break;
|
|
}
|
|
if (!model.GrowthScenario && !ScenarioType.Actuals.Equals(model.ScenarioType))
|
|
{
|
|
var actualScenario = DbContext.Scenarios.FirstOrDefault(
|
|
t => t.ParentId == model.ParentId && t.Type == (int?) ScenarioType.Actuals);
|
|
if (actualScenario != null)
|
|
{
|
|
actualScenarioId = actualScenario.Id;
|
|
actualsEndDate = actualScenario.EndDate;
|
|
if (actualScenario.StartDate < model.StartDate)
|
|
periodStartDate = actualScenario.StartDate ?? new DateTime(1900, 1, 1);
|
|
if (actualScenario.EndDate > model.EndDate)
|
|
periodEndDate = actualScenario.EndDate ?? new DateTime(1900, 1, 1);
|
|
}
|
|
else
|
|
actualsEndDate = new DateTime(1900, 1, 1);
|
|
}
|
|
else
|
|
actualsEndDate = new DateTime(1900, 1, 1);
|
|
var scenarioDetailsQuery = DbContext.VW_ScenarioAndProxyDetails.AsNoTracking()
|
|
.Where(t => t.ParentID == model.ScenarioId &&
|
|
t.WeekEndingDate >= periodStartDate &&
|
|
t.WeekEndingDate <= periodEndDate);
|
|
if (model.CreditDepartment != null)
|
|
scenarioDetailsQuery = scenarioDetailsQuery.Where(t => t.CreditId == model.CreditDepartment);
|
|
if (model.GLAccount != null)
|
|
scenarioDetailsQuery = scenarioDetailsQuery.Where(t => t.GLId == model.GLAccount);
|
|
if (model.LaborMaterials != null)
|
|
scenarioDetailsQuery = scenarioDetailsQuery.Where(t => t.CGEFX == model.LaborMaterials.ToString());
|
|
if (model.CategoryType != null)
|
|
scenarioDetailsQuery = scenarioDetailsQuery.Where(t => t.Type == (int?)model.CategoryType);
|
|
if (model.IncomeType != null)
|
|
scenarioDetailsQuery = scenarioDetailsQuery.Where(t => t.SystemAttributeOne == model.IncomeType);
|
|
var checkedExpCats = model.SelectedExpCats ?? new List<Guid>();
|
|
if (checkedExpCats.Count > 0)
|
|
scenarioDetailsQuery = scenarioDetailsQuery.Where(t => checkedExpCats.Contains(t.ExpenditureCategoryId.Value));
|
|
scenarioDetailsQuery = scenarioDetailsQuery.OrderBy(t => t.ExpenditureCategoryName).ThenBy(t => t.WeekEndingDate);
|
|
var scenarioDetails = scenarioDetailsQuery.Select(t => new
|
|
{
|
|
t.Id,
|
|
t.ExpenditureCategoryId,
|
|
t.WeekEndingDate,
|
|
t.GLId,
|
|
t.ExpenditureCategoryName,
|
|
t.Quantity,
|
|
t.Cost,
|
|
t.ParentID,
|
|
t.WeekOrdinal,
|
|
t.UseType,
|
|
t.UOMId
|
|
}).ToArray().GroupBy(
|
|
key => new
|
|
{
|
|
key.ExpenditureCategoryId,
|
|
key.ExpenditureCategoryName,
|
|
key.ParentID,
|
|
key.GLId,
|
|
key.UseType,
|
|
key.UOMId
|
|
}).ToDictionary(key => key.Key, grouping => grouping.ToList());
|
|
|
|
var totalRow = new ScenarioDetailsModel.ScenarioCalendarRow
|
|
{
|
|
ExpCatId = Guid.Empty,
|
|
ExpCatName = "Totals",
|
|
GrandTotalCost = 0,
|
|
GrandTotalQuantity = 0,
|
|
UseType = ExpenditureCategoryModel.UseTypes.Calculated
|
|
};
|
|
|
|
var scenarioCalendarGrid = new List<ScenarioDetailsModel.ScenarioCalendarRow>
|
|
{
|
|
// create a scenario calendar row for column totals
|
|
totalRow
|
|
};
|
|
if (scenarioDetails.Count > 0)
|
|
{
|
|
BuildHeaders(model, scenarioDetails.FirstOrDefault().Value.Select(t => t.WeekEndingDate ?? DateTime.MinValue).Distinct().OrderBy(o => o).ToList());
|
|
totalRow.ScenarioDetailIds = new Guid?[model.Headers.Count];
|
|
totalRow.CostValues = new decimal[model.Headers.Count];
|
|
totalRow.QuantityValues = new decimal[model.Headers.Count];
|
|
//var expenditureCategoryIds = scenarioDetails.Where(x=>x.Key.ExpenditureCategoryId.HasValue).Select(x=>x.Key.ExpenditureCategoryId.Value).Distinct().ToList<Guid>();
|
|
|
|
model.AllResources = new List<ScenarioDetailsModel.ScenarioCalendarRowResource>();
|
|
var resourcesByTeams = DbContext.Team2Project.Where(x => x.ProjectId == model.ParentId).Select(x => x.Team.PeopleResources);
|
|
foreach(var teamResource in resourcesByTeams)
|
|
{
|
|
model.AllResources.AddRange(teamResource.Select(x => new ScenarioDetailsModel.ScenarioCalendarRowResource()
|
|
{
|
|
Id = x.Id,
|
|
Name = x.FirstName + " " + x.LastName,
|
|
ExpedentureCategoryId = x.ExpenditureCategoryId,
|
|
IsActiveEmployee = x.IsActiveEmployee
|
|
}));
|
|
}
|
|
var allResIds = model.AllResources.Select(t => t.Id).Distinct().ToArray();
|
|
var allResourceVacations = DbContext.PeopleResourceVacations.Where(t => allResIds.Contains(t.PeopleResourceId)).Select(t => new
|
|
{
|
|
t.PeopleResourceId,
|
|
t.HoursOff,
|
|
t.WeekEndingDate
|
|
}).ToArray();
|
|
|
|
var allResourceTrainings = DbContext.PeopleResourceTrainings.Where(t => allResIds.Contains(t.PeopleResourceId)).Select(t => new
|
|
{
|
|
t.PeopleResourceId,
|
|
t.HoursOff,
|
|
t.WeekEndingDate
|
|
}).ToArray();
|
|
|
|
var resourceAllocation = DbContext.PeopleResourceAllocations.Where(r => r.ScenarioId == model.ScenarioId).ToList();
|
|
|
|
foreach (var row in scenarioDetails)
|
|
{
|
|
var expCatRow = new ScenarioDetailsModel.ScenarioCalendarRow
|
|
{
|
|
ExpCatId = row.Key.ExpenditureCategoryId ?? Guid.Empty,
|
|
ExpCatName = row.Key.ExpenditureCategoryName,
|
|
GrandTotalCost = 0,
|
|
GrandTotalQuantity = 0,
|
|
ScenarioDetailIds = new Guid?[model.Headers.Count],
|
|
CostValues = new decimal[model.Headers.Count],
|
|
QuantityValues = new decimal[model.Headers.Count],
|
|
UseType = (ExpenditureCategoryModel.UseTypes)row.Key.UseType,
|
|
Resources = model.AllResources.Where(x => resourceAllocation.Where(ec=>ec.ExpenditureCategoryId == row.Key.ExpenditureCategoryId ).
|
|
Select(r=>r.PeopleResourceId).Contains( x.Id)).
|
|
Select(x=> new ScenarioDetailsModel.ScenarioCalendarRowResource() {Id = x.Id, Name = x.Name,
|
|
QuantityValues = new decimal[model.Headers.Count],
|
|
CostValues = new decimal[model.Headers.Count],
|
|
CapacityQuantityValues = new decimal[model.Headers.Count],
|
|
}).ToList(),
|
|
RestQuantity = new decimal[model.Headers.Count],
|
|
RestCost = new decimal[model.Headers.Count]
|
|
};
|
|
var uomMultiplier = Utils.GetUOMMultiplier(allExpCats, allUoms, row.Key.ExpenditureCategoryId ?? Guid.Empty, model.IsUOMHours);
|
|
var uomValue = allUoms.FirstOrDefault(t => t.Id == row.Key.UOMId);
|
|
|
|
var colIndex = 0;
|
|
var monthCost = 0.0M;
|
|
var monthQuantity = 0.0M;
|
|
var resourceTotals = model.AllResources.Select(x => new Pairs() { Id = x.Id, Quantity = 0.0M }).ToList();
|
|
|
|
foreach (var column in row.Value)
|
|
{
|
|
expCatRow.ScenarioDetailIds[colIndex] = column.Id;
|
|
expCatRow.CostValues[colIndex] = column.Cost ?? 0;
|
|
expCatRow.QuantityValues[colIndex] = (column.Quantity ?? 0)*uomMultiplier;
|
|
expCatRow.GrandTotalCost += (column.Cost ?? 0);
|
|
expCatRow.GrandTotalQuantity += (column.Quantity ?? 0) * uomMultiplier;
|
|
|
|
//Get resources cost\quantity
|
|
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
|
var date = epoch.AddSeconds(model.Headers[colIndex].Milliseconds / 1000);
|
|
|
|
var currAllocation = resourceAllocation.Where(r => r.WeekEndingDate == date && r.ExpenditureCategoryId == column.ExpenditureCategoryId).ToList();
|
|
//expCatRow.Resources.ForEach(x => x.CostValues[colIndex] = (currAllocation != null ? (decimal)currAllocation.AllocatePercentage * (column.Cost ?? 0) : 0));
|
|
//expCatRow.Resources.ForEach(x => x.GrandTotalCost += (currAllocation != null ? (decimal)currAllocation.AllocatePercentage * (column.Cost ?? 0) : 0));
|
|
expCatRow.Resources.ForEach(x =>
|
|
{
|
|
// set resource weekly allocation
|
|
x.QuantityValues[colIndex] = (currAllocation.FirstOrDefault(ar => ar.PeopleResourceId == x.Id) != null
|
|
? (decimal) (currAllocation.FirstOrDefault(ar => ar.PeopleResourceId == x.Id).Quantity ?? 0)
|
|
: 0)*uomMultiplier;
|
|
// set resource weekly availability (UOM.Value - vacations - loan offs - trainings)
|
|
if (uomValue != null)
|
|
{
|
|
var vacationsSum = allResourceVacations.Where(t =>
|
|
t.PeopleResourceId == x.Id &&
|
|
t.WeekEndingDate <= date && t.WeekEndingDate >= date.AddDays(-6))
|
|
.Sum(s => s.HoursOff);
|
|
var trainingsSum = allResourceTrainings.Where(t =>
|
|
t.PeopleResourceId == x.Id &&
|
|
t.WeekEndingDate <= date && t.WeekEndingDate >= date.AddDays(-6))
|
|
.Sum(s => s.HoursOff);
|
|
x.CapacityQuantityValues[colIndex] = (uomValue.UOMValue - vacationsSum - trainingsSum) * uomMultiplier;
|
|
}
|
|
});
|
|
expCatRow.Resources.ForEach(x =>
|
|
x.GrandTotalQuantity += (currAllocation.FirstOrDefault(ar => ar.PeopleResourceId == x.Id) != null ? (decimal)(currAllocation.FirstOrDefault(ar => ar.PeopleResourceId == x.Id).Quantity ?? 0) : 0) * uomMultiplier);
|
|
expCatRow.RestQuantity[colIndex] = expCatRow.QuantityValues[colIndex] - expCatRow.Resources.Select(x => x.QuantityValues[colIndex]).Sum() * uomMultiplier;
|
|
//expCatRow.RestCost[colIndex] = expCatRow.CostValues[colIndex] - expCatRow.Resources.Select(x => x.CostValues[colIndex]).Sum();
|
|
|
|
totalRow.CostValues[colIndex] += expCatRow.CostValues[colIndex];
|
|
totalRow.QuantityValues[colIndex] += expCatRow.QuantityValues[colIndex];
|
|
|
|
expCatRow.Resources.ForEach(x => resourceTotals.FirstOrDefault(r => r.Id == x.Id).Quantity += x.QuantityValues[colIndex]);
|
|
if (colIndex < model.Headers.Count - 1)
|
|
colIndex++;
|
|
monthQuantity += (column.Quantity ?? 0.0M) * uomMultiplier;
|
|
monthCost += column.Cost ?? 0.0M;
|
|
|
|
if (colIndex >= model.Headers.Count - 1 || model.Headers[colIndex].IsMonth)
|
|
{
|
|
expCatRow.ScenarioDetailIds[colIndex] = Guid.Empty;
|
|
expCatRow.CostValues[colIndex] = monthCost;
|
|
expCatRow.QuantityValues[colIndex] = monthQuantity;
|
|
|
|
totalRow.ScenarioDetailIds[colIndex] = Guid.Empty;
|
|
totalRow.CostValues[colIndex] += monthCost;
|
|
totalRow.QuantityValues[colIndex] += monthQuantity;
|
|
|
|
expCatRow.Resources.ForEach(x => x.QuantityValues[colIndex] = resourceTotals.FirstOrDefault(r => r.Id == x.Id).Quantity);
|
|
|
|
if (colIndex < model.Headers.Count - 1)
|
|
colIndex++;
|
|
monthCost = 0.0M;
|
|
monthQuantity = 0.0M;
|
|
resourceTotals.ForEach(x=>x.Quantity = 0.0M);
|
|
}
|
|
}
|
|
scenarioCalendarGrid.Add(expCatRow);
|
|
totalRow.GrandTotalCost += expCatRow.GrandTotalCost;
|
|
totalRow.GrandTotalQuantity += expCatRow.GrandTotalQuantity;
|
|
}
|
|
}
|
|
model.ScenarioCalendar = scenarioCalendarGrid;
|
|
model.ActualsEndDateMs = (long)(actualsEndDate == null ? 0 : actualsEndDate.Value.Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds);
|
|
|
|
return model;
|
|
}
|
|
|
|
public void BuildHeaders(ScenarioDetailsModel model, List<DateTime> gridHeaders)
|
|
{
|
|
model.Headers = new List<ScenarioDetailsModel.Header>((int)(gridHeaders.Count * 1.25));
|
|
var prevMonth = string.Empty;
|
|
var monthIndex = -1;
|
|
ScenarioDetailsModel.Header monthColumn = null;
|
|
foreach (var gridHeader in gridHeaders)
|
|
{
|
|
// get week start date as previous week end date + 1 day
|
|
//var weekStartDate = prevWeek.AddDays(1);
|
|
// if there is a gap between weeks (e.g. there is a non-working week that was not represented in scenario details records)
|
|
// then we should subtract 6 days from current week end date
|
|
//if (gridHeader.AddDays(-6) > weekStartDate)
|
|
// weekStartDate = gridHeader.AddDays(-6);
|
|
// get month name as month of the week start date
|
|
var gridHeaderTitle = gridHeader.ToString("MMMM yyyy");
|
|
if (!prevMonth.Equals(gridHeaderTitle))
|
|
{
|
|
if (monthColumn != null)
|
|
{
|
|
model.Headers.Add(monthColumn);
|
|
}
|
|
monthColumn = new ScenarioDetailsModel.Header()
|
|
{
|
|
Show = true,
|
|
Milliseconds = (long)gridHeader.Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds,
|
|
MonthIndex = ++monthIndex,
|
|
IsMonth = true,
|
|
Title = gridHeaderTitle,
|
|
Weeks = new List<int>()
|
|
};
|
|
}
|
|
|
|
var weekHeader = new ScenarioDetailsModel.Header()
|
|
{
|
|
IsMonth = false,
|
|
Milliseconds = (long)gridHeader.Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds,
|
|
MonthIndex = monthColumn.MonthIndex,
|
|
Title = gridHeader.ToShortDateString()
|
|
};
|
|
model.Headers.Add(weekHeader);
|
|
monthColumn.Weeks.Add(model.Headers.Count - 1);
|
|
monthColumn.Milliseconds = weekHeader.Milliseconds;
|
|
|
|
prevMonth = gridHeaderTitle;
|
|
}
|
|
if (monthColumn != null)
|
|
{
|
|
model.Headers.Add(monthColumn);
|
|
}
|
|
}
|
|
|
|
// GET: /Scenarios/Details/5
|
|
[HttpGet]
|
|
[AreaSecurityAttribute(area = Areas.Scenarios, level = AccessLevel.Write)]
|
|
public ActionResult Details(Guid? id, string tab, string backUrl, string backName)
|
|
{
|
|
if (id == null || id == Guid.Empty)
|
|
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
var model = new ScenarioDetailModel {ActiveTab = tab};
|
|
try
|
|
{
|
|
var manager = new ScenarioManager(DbContext);
|
|
model = (ScenarioDetailModel)manager.Load(id) ?? new ScenarioDetailModel();
|
|
if (model.Id == Guid.Empty)
|
|
{
|
|
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
}
|
|
if (model.Status == null || model.Status == ScenarioStatus.Draft)
|
|
{
|
|
return RedirectToAction("Edit", "Scenarios", new {id, @backUrl = backUrl ?? Url.Action("Index", "Project"), @backName = backName ?? "projects"});
|
|
}
|
|
model.Expenditures = Utils.GetScenarioExpenditures(model.Id);
|
|
model.Projects = Utils.GetScenarioProjects(model.Id);
|
|
model.ScenarioExpenditures = manager.GetExpenditureCategories(model.Id);
|
|
model.ActiveTab = tab;
|
|
model.BackUrl = string.IsNullOrEmpty(backUrl) ? Request.QueryString["ref"] : backUrl;
|
|
model.BackName = string.IsNullOrEmpty(backName) ? Request.QueryString["back"] : backName;
|
|
model.LaborMaterialsSplit = Utils.GetLaborMaterialsSplit(model.Id);
|
|
var user = new UsersCache().Value.FirstOrDefault(x => x.Id == new Guid(HttpContext.User.Identity.GetUserId()));
|
|
if (user != null)
|
|
ViewBag.IsUOMHours = !user.PreferredResourceAllocation;
|
|
}
|
|
catch (BLLException blEx)
|
|
{
|
|
if (blEx.DisplayError)
|
|
SetErrorScript(message: blEx.Message);
|
|
else
|
|
{
|
|
LogException(blEx);
|
|
SetErrorScript();
|
|
}
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
LogException(exception);
|
|
SetErrorScript();
|
|
}
|
|
return View("Details", model);
|
|
}
|
|
|
|
// POST: /Scenarios/Details/5
|
|
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
|
|
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
[AreaSecurityAttribute(area = Areas.Scenarios, level = AccessLevel.Write)]
|
|
public ActionResult Details(ScenarioDetailModel model)
|
|
{
|
|
if (model.Id != Guid.Empty && ContentLocker.IsLock("Scenario", model.Id.ToString(), User.Identity.Name))
|
|
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
model.TrimStringProperties();
|
|
try
|
|
{
|
|
var manager = new ScenarioManager(DbContext);
|
|
manager.Save(model);
|
|
if (model.Id != Guid.Empty)
|
|
ContentLocker.RemoveLock("Scenario", model.Id.ToString(), User.Identity.Name);
|
|
if (!string.IsNullOrEmpty(model.BackUrl))
|
|
return Redirect(model.BackUrl);
|
|
else
|
|
return Details(model.Id, model.ActiveTab, model.BackUrl, model.BackName);
|
|
}
|
|
catch (BLLException blEx) // handle any system specific error
|
|
{
|
|
// display error message if required
|
|
if (blEx.DisplayError)
|
|
ModelState.AddModelError(string.Empty, blEx.Message);
|
|
else // if display not requried then display modal form with general error message
|
|
{
|
|
LogException(blEx);
|
|
SetErrorScript();
|
|
}
|
|
}
|
|
catch (Exception exception) // handle any unexpected error
|
|
{
|
|
LogException(exception);
|
|
SetErrorScript();
|
|
}
|
|
|
|
// return empty model with validation messages (if any)
|
|
if (!string.IsNullOrEmpty(model.BackUrl))
|
|
return Redirect(model.BackUrl);
|
|
return View(model);
|
|
}
|
|
|
|
[HttpGet]
|
|
public ActionResult GetScenarioAvailableExpCategories(Guid id)
|
|
{
|
|
var availableExpenditures =
|
|
DbContext.VW_ExpCategoriesInScenario.AsNoTracking()
|
|
.Where(t => t.ScenarioID == id)
|
|
.OrderBy(t => t.Name)
|
|
.Select(t => new {t.Id, t.Name})
|
|
.ToArray();
|
|
return Json(availableExpenditures, JsonRequestBehavior.AllowGet);
|
|
}
|
|
|
|
[HttpPost]
|
|
public ActionResult GetRates(Guid scenarioId, bool? uomMode)
|
|
{
|
|
var allExpCats = DbContext.ExpenditureCategory.AsNoTracking().ToList();
|
|
var allUoms = DbContext.UOMs.AsNoTracking().ToList();
|
|
if (!uomMode.HasValue)
|
|
{
|
|
var user = new UsersCache().Value.FirstOrDefault(x => x.Id == new Guid(HttpContext.User.Identity.GetUserId()));
|
|
if (user != null)
|
|
uomMode = !user.PreferredResourceAllocation;
|
|
}
|
|
|
|
#region loading rates
|
|
// retrieve all local rates for the specified scenario
|
|
var localRates = DbContext.Rates.Where(t =>
|
|
t.ParentId == scenarioId && t.Type == (int) RateModel.RateType.Derived &&
|
|
t.ExpenditureCategoryId != null)
|
|
.Select(t => new
|
|
{
|
|
t.ExpenditureCategoryId,
|
|
t.EndDate,
|
|
t.Rate1
|
|
}).OrderBy(t => t.ExpenditureCategoryId)
|
|
.ThenBy(t => t.EndDate).ToArray();
|
|
// group rates by expenditure category id and store them as disctionary by expenditure category id
|
|
var localRatesLu = localRates.GroupBy(t => t.ExpenditureCategoryId)
|
|
.ToDictionary(key => key.Key, group => group.ToList());
|
|
// retrieve similar dictionary for global rates that does not referenced to already retrieved expenditures
|
|
var globalRatesQuery = DbContext.Rates.Where(t => t.Type == (int)RateModel.RateType.Global);
|
|
//TODO: we should validate SQL query to make sure it is correct and optimal
|
|
if (localRates.Length > 0)
|
|
globalRatesQuery = globalRatesQuery.Where(t => !localRatesLu.Keys.ToList().Contains(t.ExpenditureCategoryId));
|
|
var globalRates = globalRatesQuery
|
|
.Select(t => new
|
|
{
|
|
t.ExpenditureCategoryId,
|
|
t.EndDate,
|
|
t.Rate1
|
|
})
|
|
.OrderBy(t => t.ExpenditureCategoryId).ThenBy(t => t.EndDate)
|
|
.ToArray()
|
|
.GroupBy(t => t.ExpenditureCategoryId)
|
|
.ToDictionary(key => key.Key, group => group.ToList());
|
|
// append global rates to local rates
|
|
foreach (var globalRate in globalRates)
|
|
{
|
|
if (localRatesLu.ContainsKey(globalRate.Key))
|
|
throw new BLLException("Unable to add global rate to the list because it already contains a local rate with the same key");
|
|
localRatesLu.Add(globalRate.Key, globalRate.Value);
|
|
}
|
|
#endregion
|
|
|
|
return Json(localRatesLu.Select(t=> new
|
|
{
|
|
expCatId = t.Key,
|
|
rateValues = t.Value.Select(rate => new
|
|
{
|
|
weekEndDate = (long)(rate.EndDate).Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds,
|
|
rateValue = rate.Rate1 / Utils.GetUOMMultiplier(allExpCats, allUoms, t.Key, uomMode)
|
|
})
|
|
}));
|
|
}
|
|
|
|
|
|
[HttpPost]
|
|
[AreaSecurityAttribute(area = Areas.Scenarios, level = AccessLevel.Write)]
|
|
public ActionResult CopyTo(ScenarioDetailModel model, Guid? Id, Guid[] projId, string[] projName, bool[] projChecked, ScenarioStatus copyStatus)
|
|
{
|
|
ModelState.Clear();
|
|
|
|
var checkedProject = Guid.Empty;
|
|
for (var i = 0; i < projChecked.Length; i++)
|
|
{
|
|
if (projChecked[i] && ((projId.Length - 1) >= i))
|
|
{
|
|
checkedProject = projId[i];
|
|
break;
|
|
}
|
|
}
|
|
if (Guid.Empty.Equals( checkedProject) || !Id.HasValue)
|
|
ModelState.AddModelError(string.Empty, "Invalid parameters");
|
|
else
|
|
{
|
|
EnVisageEntities context = new EnVisageEntities();
|
|
|
|
try
|
|
{
|
|
new ScenarioManager(DbContext).CopyTo(Id.Value, checkedProject, copyStatus);
|
|
|
|
var detailsGrid = "[]";
|
|
|
|
return Json(detailsGrid);
|
|
}
|
|
catch (BLLException blEx) // handle any system specific error
|
|
{
|
|
// display error message if required
|
|
if (blEx.DisplayError)
|
|
ModelState.AddModelError(string.Empty, blEx.Message);
|
|
else // if display not requried then display modal form with general error message
|
|
{
|
|
LogException(blEx);
|
|
SetErrorScript();
|
|
}
|
|
}
|
|
catch (Exception exception) // handle any unexpected error
|
|
{
|
|
LogException(exception);
|
|
SetErrorScript();
|
|
}
|
|
}
|
|
//}
|
|
HttpContext.Response.StatusCode = 500;
|
|
HttpContext.Response.Clear();
|
|
model.Projects = Utils.GetScenarioProjects(model.Id);
|
|
return PartialView("_copyToModal", model);
|
|
}
|
|
|
|
[HttpPost]
|
|
[AreaSecurityAttribute(area = Areas.Scenarios, level = AccessLevel.Write)]
|
|
public ActionResult SaveChanges(SaveScenarioDetailsChangesModel model)
|
|
{
|
|
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
|
if (model.ScenarioId != Guid.Empty && ContentLocker.IsLock("Scenario", model.ScenarioId.ToString(), User.Identity.Name))
|
|
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
var context = new EnVisageEntities();
|
|
model.TrimStringProperties();
|
|
var allExpCats = DbContext.ExpenditureCategory.AsNoTracking().ToList();
|
|
var allUoms = DbContext.UOMs.AsNoTracking().ToList();
|
|
if (!model.ScenarioFilters.IsUOMHours.HasValue)
|
|
{
|
|
var user = new UsersCache().Value.FirstOrDefault(x => x.Id == new Guid(HttpContext.User.Identity.GetUserId()));
|
|
if (user != null)
|
|
model.ScenarioFilters.IsUOMHours = !user.PreferredResourceAllocation;
|
|
}
|
|
if (ModelState.IsValid)
|
|
{
|
|
try
|
|
{
|
|
var manager = new ScenarioManager(context);
|
|
var scenario = manager.Load(model.ScenarioId, false);
|
|
var scenarioStartDateMsSince1970 = scenario.StartDate.HasValue ?
|
|
(long)scenario.StartDate.Value.Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds :
|
|
(long)new DateTime(1970, 1, 1).Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds;
|
|
|
|
foreach (var changedExpCat in model.ChangedExpCats)
|
|
{
|
|
var uomMultiplier = Utils.GetUOMMultiplier(allExpCats, allUoms, changedExpCat.Id, model.ScenarioFilters.IsUOMHours);
|
|
foreach (var changedColumn in changedExpCat.Values)
|
|
{
|
|
if (changedColumn.Milliseconds >= scenarioStartDateMsSince1970)
|
|
{
|
|
var scenarioDetailsItem = (from c in context.ScenarioDetail where c.Id == changedColumn.Id select c).FirstOrDefault();//manager.LoadScenarioDetail(changedColumn.Id, false);
|
|
if (scenarioDetailsItem == null) continue;
|
|
if ( scenarioDetailsItem.Id == Guid.Empty)
|
|
{
|
|
throw new NullReferenceException(string.Format("Scenario Details {0} mising", changedColumn.Id));
|
|
}
|
|
scenarioDetailsItem.Quantity = changedColumn.Quantity / uomMultiplier;
|
|
scenarioDetailsItem.Cost = changedColumn.Cost;
|
|
}
|
|
}
|
|
if (changedExpCat.Resources != null){
|
|
var resourceIds = changedExpCat.Resources.Select(x=>x.Id).ToList();
|
|
var resourceAllocations = context.PeopleResourceAllocations.Where(x => resourceIds.Contains(x.PeopleResourceId) && x.ScenarioId == model.ScenarioId).ToList();
|
|
foreach (var resource in changedExpCat.Resources)
|
|
{
|
|
var resourceId = resource.Id;
|
|
|
|
if (resource.IsRemoved)
|
|
{
|
|
var recourcesToDelete = context.PeopleResourceAllocations.Where(x => x.PeopleResourceId == resourceId && x.ScenarioId == model.ScenarioId).ToList();
|
|
recourcesToDelete.ForEach(x => context.PeopleResourceAllocations.Remove(x));
|
|
recourcesToDelete.ForEach(x => context.Entry(x).State = EntityState.Deleted);
|
|
}
|
|
else {
|
|
foreach (var changedResource in resource.Values)
|
|
{
|
|
var date = epoch.AddSeconds(changedResource.Milliseconds/1000);
|
|
|
|
var allocatedResource = (from c in resourceAllocations
|
|
where c.WeekEndingDate == date && c.ScenarioId == model.ScenarioId
|
|
&& c.PeopleResourceId == resourceId && c.ExpenditureCategoryId == changedExpCat.Id
|
|
select c).FirstOrDefault();
|
|
if (changedResource.Quantity <= 0)
|
|
{
|
|
if (allocatedResource != null)
|
|
context.Entry(allocatedResource).State = EntityState.Deleted;
|
|
continue;
|
|
}
|
|
if (allocatedResource == null)
|
|
{
|
|
allocatedResource = context.PeopleResourceAllocations.Create();
|
|
allocatedResource.Id = Guid.NewGuid();
|
|
allocatedResource.ExpenditureCategoryId = changedExpCat.Id;
|
|
allocatedResource.PeopleResourceId = resourceId;
|
|
allocatedResource.ScenarioId = model.ScenarioId;
|
|
allocatedResource.WeekEndingDate = date;
|
|
context.Entry(allocatedResource).State = EntityState.Added;
|
|
}
|
|
else {
|
|
context.Entry(allocatedResource).State = EntityState.Modified;
|
|
}
|
|
allocatedResource.Quantity = changedResource.Quantity / uomMultiplier;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//TODO: review that we really need 2 transactions here. Looks like it was here since bottom-up costs recalculation was in stored procedure.
|
|
context.SaveChanges();
|
|
manager.SetBottomUpCosts(scenario);
|
|
context.SaveChanges();
|
|
|
|
model.ScenarioFilters.StartDate = scenario.StartDate ?? DateTime.Today;
|
|
model.ScenarioFilters.EndDate = scenario.EndDate ?? DateTime.Today.AddYears(1);
|
|
model.ScenarioFilters.GrowthScenario = scenario.GrowthScenario;
|
|
model.ScenarioFilters.ParentId = scenario.ParentId ?? Guid.Empty;
|
|
model.ScenarioFilters.ScenarioType = (ScenarioType?)scenario.Type;
|
|
//var detailsGrid = GetScenarioCalendar(model.ScenarioFilters);
|
|
|
|
return new HttpStatusCodeResult(HttpStatusCode.OK);
|
|
}
|
|
catch (BLLException blEx) // handle any system specific error
|
|
{
|
|
// display error message if required
|
|
if (blEx.DisplayError)
|
|
ModelState.AddModelError(string.Empty, blEx.Message);
|
|
else // if display not requried then display modal form with general error message
|
|
{
|
|
LogException(blEx);
|
|
SetErrorScript();
|
|
}
|
|
}
|
|
catch (Exception exception) // handle any unexpected error
|
|
{
|
|
LogException(exception);
|
|
SetErrorScript();
|
|
}
|
|
}
|
|
return new HttpStatusCodeResult(HttpStatusCode.InternalServerError);
|
|
}
|
|
|
|
|
|
[HttpPost]
|
|
[AreaSecurityAttribute(area = Areas.Scenarios, level = AccessLevel.Write)]
|
|
public ActionResult AddNote(NoteModel model)
|
|
{
|
|
//if (model.ScenarioId != Guid.Empty && ContentLocker.IsLock("Scenario", model.ScenarioId.ToString(), User.Identity.Name))
|
|
// return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
|
|
model.TrimStringProperties();
|
|
if (ModelState.IsValid)
|
|
{
|
|
try
|
|
{
|
|
model.Id = Guid.NewGuid();
|
|
var newnote = new Note();
|
|
model.CopyTo(newnote);
|
|
newnote.UserId = new Guid(User.Identity.GetUserId());
|
|
DbContext.Notes.Add(newnote);
|
|
DbContext.SaveChanges();
|
|
}
|
|
catch (BLLException blEx) // handle any system specific error
|
|
{
|
|
// display error message if required
|
|
if (blEx.DisplayError)
|
|
ModelState.AddModelError(string.Empty, blEx.Message);
|
|
else // if display not requried then display modal form with general error message
|
|
{
|
|
LogException(blEx);
|
|
SetErrorScript();
|
|
}
|
|
}
|
|
catch (Exception exception) // handle any unexpected error
|
|
{
|
|
LogException(exception);
|
|
SetErrorScript();
|
|
}
|
|
}
|
|
return Redirect(HttpContext.Request.UrlReferrer.AbsoluteUri);
|
|
}
|
|
|
|
|
|
[HttpPost]
|
|
[AreaSecurityAttribute(area = Areas.Scenarios, level = AccessLevel.Write)]
|
|
public ActionResult EditNote(NoteModel model)
|
|
{
|
|
//if (model.ScenarioId != Guid.Empty && ContentLocker.IsLock("Scenario", model.ScenarioId.ToString(), User.Identity.Name))
|
|
// return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
|
|
model.TrimStringProperties();
|
|
if (ModelState.IsValid)
|
|
{
|
|
try
|
|
{
|
|
var note = (from c in DbContext.Notes where c.Id == model.Id select c).FirstOrDefault();
|
|
if (note == null) return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
note.Title = model.Title;
|
|
note.NoteDetail = model.Details;
|
|
DbContext.SaveChanges();
|
|
}
|
|
catch (BLLException blEx) // handle any system specific error
|
|
{
|
|
// display error message if required
|
|
if (blEx.DisplayError)
|
|
ModelState.AddModelError(string.Empty, blEx.Message);
|
|
else // if display not requried then display modal form with general error message
|
|
{
|
|
LogException(blEx);
|
|
SetErrorScript();
|
|
}
|
|
}
|
|
catch (Exception exception) // handle any unexpected error
|
|
{
|
|
LogException(exception);
|
|
SetErrorScript();
|
|
}
|
|
}
|
|
return Redirect(HttpContext.Request.UrlReferrer.AbsoluteUri);
|
|
}
|
|
|
|
// GET: /User/Edit/5
|
|
[AreaSecurityAttribute(area = Areas.Scenarios, level = AccessLevel.Write)]
|
|
public ActionResult DeleteNote(string Id)
|
|
{
|
|
if (string.IsNullOrEmpty(Id) || Id == "JSVar")
|
|
{
|
|
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
}
|
|
var NoteId = new Guid(Id);
|
|
var note = (from c in DbContext.Notes where c.Id == NoteId select c).FirstOrDefault();
|
|
if (note == null) return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
else {
|
|
DbContext.Notes.Remove(note);
|
|
DbContext.SaveChanges();
|
|
}
|
|
return Redirect(HttpContext.Request.UrlReferrer.AbsoluteUri);
|
|
}
|
|
|
|
// GET: /User/Edit/5
|
|
[AreaSecurityAttribute(area = Areas.Scenarios, level = AccessLevel.Write)]
|
|
public ActionResult EditNote(string Id)
|
|
{
|
|
if (string.IsNullOrEmpty(Id) || Id == "JSVar")
|
|
{
|
|
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
}
|
|
var NoteId = new Guid(Id);
|
|
var note = (from c in DbContext.Notes where c.Id == NoteId select c).FirstOrDefault();
|
|
if (note == null) return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
else
|
|
{
|
|
return PartialView("_addNote", (NoteModel)note);
|
|
}
|
|
}
|
|
// GET: /User/Edit/5
|
|
[AreaSecurityAttribute(area = Areas.Scenarios, level = AccessLevel.Write)]
|
|
public ActionResult AddNote(string Id)
|
|
{
|
|
if (string.IsNullOrEmpty(Id))
|
|
{
|
|
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
}
|
|
var ParentId = new Guid(Id);
|
|
return PartialView("_addNote", new NoteModel(ParentId));
|
|
}
|
|
|
|
[AreaSecurityAttribute(area = Areas.Scenarios, level = AccessLevel.Write)]
|
|
public ActionResult EditRate(Guid? id, Guid? parentId, Guid expentureCategoryId)
|
|
{
|
|
RateModel model = null;
|
|
if (id.HasValue && id != Guid.Empty)
|
|
{
|
|
var manager = new RateManager(DbContext);
|
|
model = (RateModel)manager.Load(id);
|
|
}
|
|
else
|
|
{
|
|
var sManager = new ScenarioManager(DbContext);
|
|
var scenario = sManager.Load(parentId);
|
|
model = new RateModel();
|
|
model.Type = RateModel.RateType.Derived;
|
|
var lRates = (from c in DbContext.Rates
|
|
where
|
|
c.ExpenditureCategoryId == expentureCategoryId &&
|
|
c.Type == (int)RateModel.RateType.Derived &&
|
|
c.ParentId == parentId
|
|
select c).ToList();
|
|
if ((from d in lRates select d.EndDate).Max() < DateTime.MaxValue.AddYears(-4))
|
|
{
|
|
model.StartDate = (lRates.Count == 0) ? scenario.StartDate.Value : ((from d in lRates select d.EndDate).Max()).AddDays(1);
|
|
model.EndDate = scenario.EndDate.Value;
|
|
}
|
|
else
|
|
{
|
|
model.StartDate = (from d in lRates select d.EndDate).Max();
|
|
model.EndDate = model.StartDate;
|
|
}
|
|
}
|
|
|
|
if ((!model.ParentId.HasValue || model.ParentId == Guid.Empty) && parentId.HasValue)
|
|
model.ParentId = parentId;
|
|
if (model.ExpenditureCategoryId == Guid.Empty)
|
|
model.ExpenditureCategoryId = expentureCategoryId;
|
|
|
|
return PartialView("_editRate", model);
|
|
}
|
|
|
|
[HttpPost]
|
|
[AreaSecurityAttribute(area = Areas.Scenarios, level = AccessLevel.Write)]
|
|
public ActionResult EditRate(RateModel model)
|
|
{
|
|
if (ContentLocker.IsLock("Rate", model.Id.ToString(), User.Identity.Name))
|
|
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
|
|
if(ModelState.IsValid)
|
|
{
|
|
var manager = new RateManager(DbContext);
|
|
manager.Save(model);
|
|
DbContext.SaveChanges();
|
|
manager.Dispose();
|
|
}
|
|
|
|
ContentLocker.RemoveLock("Rate", model.Id.ToString(), User.Identity.Name);
|
|
return JavaScript("window.location.search += '&tab=rateTable';");
|
|
//ProcessRates(new RatesModel() {
|
|
//ExpenditureCategoryId = model.ExpenditureCategoryId,
|
|
//ScenarioId = model.ParentId.Value,
|
|
//Mode = RatesModel.FormMode.ListRates });
|
|
}
|
|
|
|
[AreaSecurityAttribute(area = Areas.Scenarios, level = AccessLevel.Write)]
|
|
public ActionResult DeleteRate(Guid? id)
|
|
{
|
|
RateModel model = null;
|
|
if (id.HasValue && id != Guid.Empty)
|
|
{
|
|
var manager = new RateManager(DbContext);
|
|
model = (RateModel)manager.Load(id);
|
|
}
|
|
else
|
|
model = new RateModel();
|
|
|
|
return PartialView("_deleteRate", model);
|
|
}
|
|
|
|
[HttpPost]
|
|
[AreaSecurityAttribute(area = Areas.Scenarios, level = AccessLevel.Write)]
|
|
public ActionResult DeleteRate(RateModel model)
|
|
{
|
|
if (ContentLocker.IsLock("Rate", model.Id.ToString(), User.Identity.Name))
|
|
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
|
|
if (ModelState.IsValid)
|
|
{
|
|
var dbObj = DbContext.Rates.FirstOrDefault(x => x.Id == model.Id);
|
|
DbContext.Rates.Remove(dbObj);
|
|
DbContext.SaveChanges();
|
|
}
|
|
|
|
ContentLocker.RemoveLock("Rate", model.Id.ToString(), User.Identity.Name);
|
|
return ProcessRates(new RatesModel()
|
|
{
|
|
ExpenditureCategoryId = model.ExpenditureCategoryId,
|
|
ScenarioId = model.ParentId.Value,
|
|
Mode = RatesModel.FormMode.ListRates
|
|
});
|
|
}
|
|
|
|
public ActionResult GetMonthEndDates(DateTime? StartDate, DateTime? EndDate)
|
|
{
|
|
var s = StartDate.Value;
|
|
var e = EndDate.Value;
|
|
|
|
var dates = (from c in DbContext.FiscalCalendars where c.Type == 1 && c.StartDate >= s && c.EndDate <= e orderby c.StartDate select c.EndDate);
|
|
|
|
var list = new List<double>();
|
|
foreach (var d in dates)
|
|
list.Add(d.Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds);
|
|
|
|
return Json(list, JsonRequestBehavior.AllowGet);
|
|
}
|
|
|
|
[HttpGet]
|
|
public JsonResult GetTeamCapacityScenarioId(Guid teamId)
|
|
{
|
|
using (var context = new EnVisageEntities())
|
|
{
|
|
var data = (from sd in context.Teams
|
|
where sd.Id == teamId
|
|
select sd.PlannedCapacityScenarioId).FirstOrDefault();
|
|
if (data == null) {
|
|
var teamManager = new TeamManager(DbContext);
|
|
var team = teamManager.Load(teamId, false);
|
|
var scen = new Scenario();
|
|
scen.Name = team.Name.Trim() + " Planned Capacity";
|
|
scen.Type = (int)ScenarioType.TeamPlannedCapacity;
|
|
scen.Id = Guid.NewGuid();
|
|
team.PlannedCapacityScenarioId = scen.Id;
|
|
DbContext.Scenarios.Add(scen);
|
|
DbContext.SaveChanges();
|
|
data = scen.Id;
|
|
}
|
|
return Json((data == null) ? string.Empty : data.ToString(), JsonRequestBehavior.AllowGet);
|
|
}
|
|
|
|
}
|
|
|
|
// GET: /Scenario/Delete/5
|
|
[HttpGet]
|
|
[AreaSecurityAttribute(area = Areas.Scenarios, level = AccessLevel.Write)]
|
|
public ActionResult Delete(Guid? id, string backUrl = null)
|
|
{
|
|
if (id == null || id == Guid.Empty)
|
|
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
|
|
var model = new ScenarioModel();
|
|
try
|
|
{
|
|
var manager = new ScenarioManager(DbContext);
|
|
model = (ScenarioModel)manager.Load(id);
|
|
if (model == null)
|
|
return HttpNotFound();
|
|
}
|
|
catch (BLLException blEx)
|
|
{
|
|
if (blEx.DisplayError)
|
|
SetErrorScript(message: blEx.Message);
|
|
else
|
|
{
|
|
LogException(blEx);
|
|
SetErrorScript();
|
|
}
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
LogException(exception);
|
|
SetErrorScript();
|
|
}
|
|
return View(model);
|
|
}
|
|
|
|
// POST: /Scenario/Delete/5
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
[AreaSecurityAttribute(area = Areas.Scenarios, level = AccessLevel.Write)]
|
|
public ActionResult Delete(ScenarioModel model)
|
|
{
|
|
if (ContentLocker.IsLock("Scenario", model.Id.ToString(), User.Identity.Name))
|
|
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
|
|
var manager = new ScenarioManager(DbContext);
|
|
var dbObj = manager.Load(model.Id, false);
|
|
if (dbObj == null)
|
|
return HttpNotFound();
|
|
(DbContext as IObjectContextAdapter).ObjectContext.ExecuteStoreCommand(string.Format("exec sp_DeleteScenario '{0}'", dbObj.Id));
|
|
DbContext.SaveChanges();
|
|
ContentLocker.RemoveLock("Scenario", dbObj.Id.ToString(), User.Identity.Name);
|
|
|
|
if (Request["backUrl"] != null)
|
|
{
|
|
return Redirect(Request["backUrl"]);
|
|
}
|
|
else
|
|
{
|
|
return RedirectToAction("Index", "Project");
|
|
}
|
|
}
|
|
|
|
[AreaSecurityAttribute(area = Areas.Scenarios, level = AccessLevel.Write)]
|
|
public ActionResult AdjustMargin(Guid? id)
|
|
{
|
|
var manager = new ScenarioManager(DbContext);
|
|
var scenario = (ScenarioModel)manager.Load(id, false) ?? new ScenarioModel();
|
|
var project = DbContext.Projects.FirstOrDefault(x => x.Id == scenario.ParentId);
|
|
var model = new UpdateScenarioModel()
|
|
{
|
|
Id = scenario.Id,
|
|
EndDate = scenario.EndDate,
|
|
Expenditures = scenario.Expenditures,
|
|
GrossMargin = scenario.GrossMargin,
|
|
LMMargin = scenario.LMMargin,
|
|
TDDirectCosts = scenario.TDDirectCosts,
|
|
ProjectedRevenue = scenario.ProjectedRevenue,
|
|
StartDate = scenario.StartDate,
|
|
UseLMMargin = scenario.UseLMMargin,
|
|
AllowAdjustment = scenario.AllowAdjustment,
|
|
PriorWeekCutOff = scenario.PriorWeekCutOff ?? scenario.StartDate,
|
|
BUDirectCosts = scenario.BUDirectCosts
|
|
};
|
|
|
|
if (project != null)
|
|
model.IsRevenueGenerating = project.IsRevenueGenerating;
|
|
else
|
|
model.IsRevenueGenerating = false;
|
|
|
|
|
|
model.Expenditures = manager.GetExpenditureCategories(model.Id);
|
|
|
|
return PartialView("_adjustMargin", model);
|
|
}
|
|
|
|
[HttpPost]
|
|
[AreaSecurityAttribute(area = Areas.Scenarios, level = AccessLevel.Write)]
|
|
public ActionResult AdjustMargin(UpdateScenarioModel model, Guid[] expCatId, string[] expCatName, string[] expCatGroup, bool[] expCatChecked)
|
|
{
|
|
if (ContentLocker.IsLock("Scenario", model.Id.ToString(), User.Identity.Name))
|
|
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
|
|
model.TrimStringProperties();
|
|
|
|
if (expCatId != null && expCatName != null && expCatGroup != null && expCatChecked != null &&
|
|
expCatId.Length == expCatName.Length && expCatId.Length == expCatGroup.Length && expCatId.Length == expCatChecked.Length)
|
|
{
|
|
model.Expenditures = new ScenarioModel.ExpenditureItem[expCatId.Length];
|
|
for (var i = 0; i < expCatId.Length; i++)
|
|
{
|
|
model.Expenditures[i] = new ScenarioModel.ExpenditureItem
|
|
{
|
|
Id = expCatId[i],
|
|
Group = expCatGroup[i],
|
|
Name = expCatName[i],
|
|
Checked = expCatChecked[i]
|
|
};
|
|
}
|
|
}
|
|
|
|
try
|
|
{
|
|
// get scenario by id
|
|
var manager = new ScenarioManager(DbContext);
|
|
var scenario = (ScenarioModel)manager.Load(model.Id);
|
|
|
|
var project = DbContext.Projects.FirstOrDefault(x => x.Id == scenario.ParentId);
|
|
if (project != null)
|
|
model.IsRevenueGenerating = project.IsRevenueGenerating;
|
|
else
|
|
model.IsRevenueGenerating = false;
|
|
|
|
if(ModelState.IsValid)
|
|
{
|
|
// update scenario values
|
|
scenario.StartDate = model.StartDate;
|
|
scenario.EndDate = model.EndDate;
|
|
scenario.GrossMargin = model.UseLMMargin ? null : model.GrossMargin;//!model.UseLMMargin ? model.GrossMargin / 100 : null;
|
|
scenario.LMMargin = model.UseLMMargin ? model.LMMargin : null;
|
|
scenario.TDDirectCosts = model.TDDirectCosts;
|
|
scenario.ProjectedRevenue = model.ProjectedRevenue;
|
|
scenario.PriorWeekCutOff = model.PriorWeekCutOff;
|
|
scenario.AllowAdjustment = model.AllowAdjustment;
|
|
scenario.UseLMMargin = model.UseLMMargin;
|
|
scenario.Expenditures = model.Expenditures;
|
|
scenario.FreezeResource = model.AllowAdjustment;
|
|
|
|
manager.Save(scenario);
|
|
|
|
ContentLocker.RemoveLock("Scenario", model.Id.ToString(), User.Identity.Name);
|
|
return Json(new { Status = "Ok" });
|
|
}
|
|
|
|
}
|
|
catch (BLLException blEx)
|
|
{
|
|
if (blEx.DisplayError)
|
|
SetErrorScript(message: blEx.Message);
|
|
else
|
|
{
|
|
LogException(blEx);
|
|
SetErrorScript();
|
|
}
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
LogException(exception);
|
|
SetErrorScript();
|
|
ModelState.AddModelError("errors", "Error on adjust scenario.");
|
|
}
|
|
|
|
ContentLocker.RemoveLock("Scenario", model.Id.ToString(), User.Identity.Name);
|
|
return PartialView("_adjustMargin", model);
|
|
}
|
|
|
|
[HttpPost]
|
|
[AreaSecurityAttribute(area = Areas.Scenarios, level = AccessLevel.Write)]
|
|
public ActionResult CreateTemplate(ScenarioTemplateCreationModel model, Guid[] expCatId, string[] expCatName, string[] expCatGroup, bool[] templateExpCatChecked)
|
|
{
|
|
if (ContentLocker.IsLock("Scenario", model.Id.ToString(), User.Identity.Name))
|
|
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
|
|
model.TrimStringProperties();
|
|
|
|
if (expCatId != null && expCatName != null && expCatGroup != null && templateExpCatChecked != null &&
|
|
expCatId.Length == expCatName.Length && expCatId.Length == expCatGroup.Length && expCatId.Length == templateExpCatChecked.Length)
|
|
{
|
|
model.Expenditures = new ScenarioModel.ExpenditureItem[expCatId.Length];
|
|
for (var i = 0; i < expCatId.Length; i++)
|
|
{
|
|
model.Expenditures[i] = new ScenarioModel.ExpenditureItem
|
|
{
|
|
Id = expCatId[i],
|
|
Group = expCatGroup[i],
|
|
Name = expCatName[i],
|
|
Checked = templateExpCatChecked[i]
|
|
};
|
|
}
|
|
}
|
|
var expCatIds = (from e in model.Expenditures where e.Checked == true select e.Id).ToArray();
|
|
|
|
try
|
|
{
|
|
// get scenario by id
|
|
var manager = new ScenarioManager(DbContext);
|
|
var scenario = manager.Load(model.Id);
|
|
|
|
if (ModelState.IsValid)
|
|
{
|
|
var newTemplate = DbContext.Scenarios.Create();
|
|
newTemplate.Id = Guid.NewGuid();
|
|
newTemplate.Name = model.TemplateName;
|
|
newTemplate.ParentId = null;
|
|
newTemplate.TemplateId = null;
|
|
newTemplate.Type = (int)ScenarioType.Template;
|
|
newTemplate.ProjectedRevenue = 0;
|
|
newTemplate.ExpectedGrossMargin = 0;
|
|
newTemplate.CalculatedGrossMargin = 0;
|
|
newTemplate.CGSplit = scenario.CGSplit;
|
|
newTemplate.EFXSplit = scenario.EFXSplit;
|
|
newTemplate.StartDate = null;
|
|
newTemplate.EndDate = null;
|
|
newTemplate.Duration = scenario.Duration;
|
|
newTemplate.TDDirectCosts = 0;
|
|
newTemplate.BUDirectCosts = 0;
|
|
newTemplate.Shots = scenario.Shots;
|
|
newTemplate.TDRevenueShot = 0;
|
|
newTemplate.BURevenueShot = 0;
|
|
newTemplate.FreezeRevenue = false;
|
|
newTemplate.Color = null;
|
|
newTemplate.Status = (int)ScenarioStatus.Active;
|
|
newTemplate.UseLMMargin = scenario.UseLMMargin;
|
|
newTemplate.ExpectedGrossMargin_LM = scenario.ExpectedGrossMargin_LM;
|
|
newTemplate.CalculatedGrossMargin_LM = scenario.CalculatedGrossMargin_LM;
|
|
newTemplate.TDDirectCosts_LM = 0;
|
|
newTemplate.BUDirectCosts_LM = 0;
|
|
newTemplate.BURevenueShot_LM = 0;
|
|
newTemplate.ShotStartDate = null;
|
|
newTemplate.GrowthScenario = scenario.GrowthScenario;
|
|
newTemplate.Actuals_BUDirectCosts = 0;
|
|
newTemplate.Actuals_BUDirectCosts_LM = 0;
|
|
newTemplate.SystemAttributeObjectID = scenario.SystemAttributeObjectID;
|
|
DbContext.Entry(newTemplate).State = EntityState.Added;
|
|
DbContext.SaveChanges();
|
|
|
|
var sds = DbContext.ScenarioDetail.Where(s => s.ParentID == scenario.Id && expCatIds.Contains(s.ExpenditureCategoryId.Value)).ToList();
|
|
foreach (var scenarioDetails in sds)
|
|
{
|
|
|
|
var copiedScenarioDetails = DbContext.ScenarioDetail.Create();
|
|
copiedScenarioDetails.Cost = scenarioDetails.Cost;
|
|
copiedScenarioDetails.Id = Guid.NewGuid();
|
|
copiedScenarioDetails.ParentID = newTemplate.Id;
|
|
copiedScenarioDetails.ExpenditureCategoryId = scenarioDetails.ExpenditureCategoryId;
|
|
copiedScenarioDetails.WeekEndingDate = null;
|
|
copiedScenarioDetails.Quantity = scenarioDetails.Quantity;
|
|
copiedScenarioDetails.WeekOrdinal = scenarioDetails.WeekOrdinal;
|
|
|
|
DbContext.Entry(copiedScenarioDetails).State = EntityState.Added;
|
|
}
|
|
DbContext.SaveChanges();
|
|
|
|
ContentLocker.RemoveLock("Scenario", model.Id.ToString(), User.Identity.Name);
|
|
return Json(new { Status = "Ok" });
|
|
}
|
|
|
|
}
|
|
catch (BLLException blEx)
|
|
{
|
|
if (blEx.DisplayError)
|
|
SetErrorScript(message: blEx.Message);
|
|
else
|
|
{
|
|
LogException(blEx);
|
|
SetErrorScript();
|
|
}
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
LogException(exception);
|
|
SetErrorScript();
|
|
ModelState.AddModelError("errors", "Error on adjust scenario.");
|
|
}
|
|
|
|
ContentLocker.RemoveLock("Scenario", model.Id.ToString(), User.Identity.Name);
|
|
return View(model);
|
|
}
|
|
|
|
[HttpPost]
|
|
public JsonResult GetScenarioResources(Guid? scenarioId)
|
|
{
|
|
if (scenarioId.HasValue && scenarioId != Guid.Empty)
|
|
{
|
|
try
|
|
{
|
|
var expCats = DbContext.VW_ExpCategoriesInScenario.Where(x => x.ScenarioID == scenarioId)
|
|
.Select(x => x.Id).ToList();
|
|
|
|
var teamsIds = DbContext.Scenarios.FirstOrDefault(x => x.Id == scenarioId)
|
|
.Project.Company.Teams.Select(t => t.Id).ToList();
|
|
|
|
var resources = new List<object>();
|
|
foreach(var id in expCats)
|
|
{
|
|
resources.AddRange(DbContext.PeopleResources
|
|
.Where(x => x.ExpenditureCategory != null && x.ExpenditureCategory.Id == id)
|
|
.Select(x => new
|
|
{
|
|
Id = x.Id,
|
|
Name = x.FirstName + " " + x.LastName,
|
|
Team = x.Team != null ? new { Id = x.Team.Id, Name = x.Team.Name } : null,
|
|
ExpenditureCategories = x.ExpenditureCategory.Id
|
|
}));
|
|
}
|
|
|
|
return Json(new { Status = "Ok", Data = resources });
|
|
}
|
|
catch(Exception ex)
|
|
{
|
|
LogException(ex);
|
|
return Json(new { Status = "Error", Msg = ex.Message });
|
|
}
|
|
}
|
|
else
|
|
return Json(new { Status = "Error", Msg = "Param 'scenarioId' can't be null or empty." });
|
|
}
|
|
|
|
[HttpPost]
|
|
public JsonResult GetTeamScenarioResources(Guid? scenarioId)
|
|
{
|
|
if (scenarioId.HasValue && scenarioId != Guid.Empty)
|
|
{
|
|
try
|
|
{
|
|
var expCats = DbContext.VW_ExpCategoriesInScenario.Where(x => x.ScenarioID == scenarioId)
|
|
.Select(x => x.Id).ToList();
|
|
|
|
var team = DbContext.Teams.FirstOrDefault(x => x.PlannedCapacityScenarioId == scenarioId);
|
|
var teamId = team.Id;
|
|
var teamName = team.Name;
|
|
var resources = new List<object>();
|
|
foreach (var id in expCats)
|
|
{
|
|
resources.AddRange(DbContext.PeopleResources
|
|
.Where(x => x.ExpenditureCategory != null && x.ExpenditureCategory.Id == id).AsEnumerable()
|
|
.Select(x => new
|
|
{
|
|
Id = x.Id,
|
|
Name = x.FirstName + " " + x.LastName,
|
|
Team = new { Id = teamId, Name = teamName },
|
|
ExpenditureCategories = x.ExpenditureCategory.Id
|
|
}));
|
|
}
|
|
|
|
return Json(new { Status = "Ok", Data = resources });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogException(ex);
|
|
return Json(new { Status = "Error", Msg = ex.Message });
|
|
}
|
|
}
|
|
else
|
|
return Json(new { Status = "Error", Msg = "Param 'scenarioId' can't be null or empty." });
|
|
}
|
|
|
|
[HttpPost]
|
|
[AreaSecurityAttribute(area = Areas.Scenarios, level = AccessLevel.Write)]
|
|
public ActionResult DeleteAllLocalRates(Guid? scenarioId, Guid? expenditureCategoryId)
|
|
{
|
|
if (!scenarioId.HasValue || scenarioId == Guid.Empty || !expenditureCategoryId.HasValue || expenditureCategoryId == Guid.Empty)
|
|
return Json(new { Status = "Error", Msg = "Parameter scenarioId or expenditureCategoryId can not be null or empty." });
|
|
|
|
if (ContentLocker.IsLock("Scenario", scenarioId.ToString(), User.Identity.Name))
|
|
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
|
|
|
|
try
|
|
{
|
|
var ratesForDelete = DbContext.Rates
|
|
.Where(x => x.ParentId == scenarioId &&
|
|
x.ExpenditureCategoryId == expenditureCategoryId &&
|
|
x.Type == (short)RateModel.RateType.Derived);
|
|
DbContext.Rates.RemoveRange(ratesForDelete);
|
|
DbContext.SaveChanges();
|
|
|
|
ContentLocker.RemoveLock("Scenario", scenarioId.ToString(), User.Identity.Name);
|
|
|
|
return Json(new { Status = "Ok" });
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
LogException(exception);
|
|
return Json(new { Status = "Error", Msg = exception.Message });
|
|
}
|
|
}
|
|
}
|
|
} |