using EnVisage.Code.DAL.Mongo;
using EnVisage.Models;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace EnVisage.Code.BLL
{
///
/// Does merging of client changes model to server model
///
public class MixModelsMergeManager
{
public MixModelsMergeManager(EnVisageEntities dbContext, string userId)
{
this.dbContext = dbContext;
this._userId = userId;
}
protected EnVisageEntities dbContext = null;
protected string _userId = string.Empty;
public void MergeFilters(MixFilterModel serverModel, MixFilterModel clientModel)
{
if ((clientModel == null) || (clientModel.Selection == null))
return;
if (serverModel == null)
throw new ArgumentNullException("serverModel");
if (serverModel.Selection == null)
serverModel.Selection = new MixFilterSelectionModel();
serverModel.Selection.StartDate = clientModel.Selection.StartDate;
serverModel.Selection.EndDate = clientModel.Selection.EndDate;
serverModel.Selection.TeamsViews = clientModel.Selection.TeamsViews.Select(c => new MixTeamViewModel()
{
Id = c.Id,
IsNew = c.IsNew,
TVName = c.TVName,
Group = new SelectListGroup { Name = c.Group.Name, Disabled = false },
CompanyId = c.CompanyId,
CostCenterId = c.CostCenterId,
CapacityTeamId = c.CapacityTeamId,
CopyPlanned = c.CopyPlanned,
UserId = (c.UserId != null) ? c.UserId.Select(u => u).ToArray() : null,
Data = (c.Data != null) ? c.Data.Where(d => (d != null)).Select(r => new WidgetExpCategory()
{
Id = r.Id,
Name = r.Name,
InPlan = r.InPlan,
Positions = (r.Positions != null) ? r.Positions.Where(a => (a != null)).Select(p =>
new WidgetExpCatPosition()
{
StartDate = p.StartDate,
EndDate = p.EndDate,
Need = p.Need,
SDate = null,
EDate = null
}).ToArray() : null
}).ToArray() : null
}).ToList();
}
public void MergeHeaders(MixSaveModel serverModel, MixSaveModel clientModel)
{
serverModel.Id = clientModel.Id;
serverModel.Name = clientModel.Name;
serverModel.StartDate = clientModel.StartDate;
serverModel.EndDate = clientModel.EndDate;
serverModel.CreatedBy = clientModel.CreatedBy;
if (clientModel.Users != null)
{
if (serverModel.Users == null)
serverModel.Users = new List();
List usersToAppend = clientModel.Users.Where(u => !serverModel.Users.Contains(u)).ToList();
serverModel.Users.AddRange(usersToAppend);
}
}
///
/// Merges two collections of data
///
/// Actual data taken from alive database
/// Mix data taken from Mongo
///
///
public void MergeCalendars(MixSaveModel serverModel, MixSaveModel clientModel, DateTime periodStartWeekending, DateTime periodEndWeekending)
{
if (serverModel?.Calendar == null)
return;
if (clientModel?.Calendar == null)
return;
var mixManager = new MongoMixManager(dbContext, _userId);
// Convert period bound dates to Unix
long startDateUnix = GetUnixDate(periodStartWeekending);
long endDateUnix = GetUnixDate(periodEndWeekending);
MergeExpendituresNeedModel(serverModel.Calendar, clientModel.Calendar);
MergeTeamCollections(serverModel.Calendar, clientModel.Calendar);
MergeProjectCollections(serverModel.Calendar, clientModel.Calendar);
SortProjects(serverModel.Calendar, startDateUnix, endDateUnix);
MergeProjectLists(serverModel.Calendar, clientModel.Calendar);
MergeLayouts(serverModel.Calendar, clientModel.Calendar);
// gather deleted projects
SetDeletedFromLiveDbProjects(serverModel, clientModel.Calendar, periodStartWeekending, periodEndWeekending.AddDays(6));
// fill deleted resource names
var deletedResourceKeys = serverModel.Calendar.ModifiedObjects.DeletedResources.Keys.Select(t => Guid.Parse(t)).ToList();
if (deletedResourceKeys.Count > 0 && !string.IsNullOrWhiteSpace(clientModel.Id))
{
var resNames = mixManager.GetResourceNames(clientModel.Id, deletedResourceKeys);
if (resNames != null)
foreach (var item in resNames)
{
if (serverModel.Calendar.ModifiedObjects.DeletedResources.ContainsKey(item.Key))
serverModel.Calendar.ModifiedObjects.DeletedResources[item.Key] = item.Value;
}
}
}
protected void MergeProjectCollections(MixCalendarModel serverCalendarModel,
MixCalendarModel clientCalendarModel)
{
if (serverCalendarModel == null)
throw new ArgumentNullException(nameof(serverCalendarModel));
if (serverCalendarModel.Projects == null)
serverCalendarModel.Projects = new Dictionary();
if (clientCalendarModel?.Projects == null)
return;
// Get project list to update (exist in both models)
List projectsToUpdate = serverCalendarModel.Projects.Where(p =>
clientCalendarModel.Projects.ContainsKey(p.Key)).Select(p => p.Key).ToList();
foreach (string projectId in projectsToUpdate)
{
MixProjectModel serverProjectItem = serverCalendarModel.Projects[projectId];
MixProjectModel clientProjectItem = clientCalendarModel.Projects[projectId];
MergeSingleProjectModels(serverProjectItem, clientProjectItem,
serverCalendarModel.Teams, clientCalendarModel.Teams);
}
}
///
/// ???
///
/// ?
/// ?
/// A list of Teams from Mix filter which exist in SQL database.
/// A list of Teams from Mix filter which exist in Mongo database.
protected void MergeSingleProjectModels(MixProjectModel serverProjectModel,
MixProjectModel clientProjectModel, List serverMixTeams,
List clientMixTeams)
{
MergeProjectVersions(serverProjectModel, clientProjectModel);
if ((clientProjectModel.Teams != null) && (serverMixTeams != null) && (clientMixTeams != null))
{
// Merging of project Teams
List serverTeamsInMix = serverMixTeams.Select(t => new Guid(t.Id)).ToList();
List clientNewTeamsInMix = clientMixTeams.Where(t => t.IsNew).Select(t => new Guid(t.Id)).ToList();
List teamsForProject = new List();
// Include all client model teams
teamsForProject.AddRange(clientProjectModel.Teams);
// Remove all teams, that are not new in Mix and does not exist in SQL database
teamsForProject.RemoveAll(t => !clientNewTeamsInMix.Contains(t) && !serverTeamsInMix.Contains(t));
serverProjectModel.Teams = teamsForProject;
}
}
protected void MergeTeamCollections(MixCalendarModel serverCalendarModel, MixCalendarModel clientCalendarModel)
{
if (serverCalendarModel.Teams == null)
throw new ArgumentNullException("serverCalendarModel.Teams");
if (clientCalendarModel.Teams == null)
return;
var resourceManager = (new PeopleResourcesManager(dbContext));
var clientResources = clientCalendarModel.Teams.SelectMany(x => x.ExpCategories)
.SelectMany(x => x.Value.Resources)
.Select(x => Guid.Parse(x.Key));
var serverResources = resourceManager.GetPeopleResourceWithTeams4Resources(clientResources).Select(x => x.Id);
var deletedResources = clientResources.Except(serverResources);
// Merging of teams, that exist both in server and client models
// serverModel must have all new teams from clientModel (as a result of the MixController.GetCalendar method)
foreach (var clientTeam in clientCalendarModel.Teams)
{
var serverTeam = serverCalendarModel.Teams.FirstOrDefault(t => t.Id.Equals(clientTeam.Id));
if (serverTeam != null && !string.IsNullOrWhiteSpace(serverTeam.Id))
MergeSingleTeamModels(serverTeam, clientTeam, serverCalendarModel, deletedResources);
}
// Check, if some new teams in client Model doesn't exist in server Model.
// If so, write here code for adding absent teams
}
protected void MergeSingleTeamModels(MixTeamModel serverTeamModel, MixTeamModel clientTeamModel, MixCalendarModel serverCalendarModel, IEnumerable deletedResources)
{
if (serverTeamModel == null)
throw new ArgumentNullException("serverTeamModel");
if (clientTeamModel == null)
throw new ArgumentNullException("clientTeamModel");
serverTeamModel.CompanyId = clientTeamModel.CompanyId ?? serverTeamModel.CompanyId;
serverTeamModel.CostCenterId = clientTeamModel.CostCenterId;
serverTeamModel.Name = clientTeamModel.Name;
serverTeamModel.UserId = clientTeamModel.UserId;
var serverExpCatsBackup = serverTeamModel.ExpCategories;
// planned capacity should be rewritten from Mongo only for new teams that do not have capacity saved in the live database
if (clientTeamModel.IsNew)
serverTeamModel.PlannedCapacity = clientTeamModel.PlannedCapacity != null ? clientTeamModel.PlannedCapacity.Clone() : null;
var categories = new Dictionary();
if (clientTeamModel.ExpCategories != null)
{
foreach (var category in clientTeamModel.ExpCategories.Values)
{
var categoryKey = category.Id.ToString();
var backupCategory = serverExpCatsBackup.ContainsKey(categoryKey) ? serverExpCatsBackup[categoryKey] : null;
var serverCategory = new ExpCategorySummaryInfoModel()
{
Id = category.Id,
Name = category.Name,
UomValue = category.UomValue,
AllowResourceAssignment = category.AllowResourceAssignment,
ECScenario = serverTeamModel.ExpCategories.ContainsKey(categoryKey) ? serverTeamModel.ExpCategories[categoryKey].ECScenario : ExpCategorySummaryInfoModel.EC_Scenario.UNKNOWN,
AllocatedCapacity = (category.AllocatedCapacity != null) ?
category.AllocatedCapacity.Select(ac =>
new KeyValuePair(ac.Key, ac.Value))
.ToDictionary(ac => ac.Key, ac => ac.Value) : new Dictionary(),
NeedCapacity = (category.NeedCapacity != null) ?
category.NeedCapacity.Select(ac =>
new KeyValuePair(ac.Key, ac.Value))
.ToDictionary(ac => ac.Key, ac => ac.Value) : new Dictionary(),
ActualCapacityValues = new Dictionary(),
PlannedCapacityValues = new Dictionary(),
Resources = new Dictionary()
};
if (category.Resources != null)
{
foreach (var resource in category.Resources.Values)
{
var deletedResource = deletedResources?.FirstOrDefault(t => t == resource.Id);
if (deletedResource != null && !Guid.Empty.Equals(deletedResource))
{
if (!serverCalendarModel.ModifiedObjects.DeletedResources.ContainsKey(resource.Id.ToString()))
serverCalendarModel.ModifiedObjects.DeletedResources.Add(resource.Id.ToString(), string.Empty);
if ((serverCategory.AllocatedCapacity != null) && (resource.AllocatedCapacity != null))
{
// Decrease server category Allocated Capacity with deleted Resource allocation values
foreach (var resourceWe in resource.AllocatedCapacity.Keys)
{
if (serverCategory.AllocatedCapacity.ContainsKey(resourceWe))
{
var valueToDecrease = resource.AllocatedCapacity[resourceWe];
var catSourceAllocationValue = serverCategory.AllocatedCapacity[resourceWe];
serverCategory.AllocatedCapacity[resourceWe] = (catSourceAllocationValue >= valueToDecrease) ?
catSourceAllocationValue - valueToDecrease : 0;
}
}
}
continue;
}
var resourceKey = resource.Id.ToString();
var serverResource = new ResourceSummaryInfoModel()
{
Id = resource.Id,
AllocatedCapacity = (resource.AllocatedCapacity != null) ?
resource.AllocatedCapacity.Select(r =>
new KeyValuePair(r.Key, r.Value))
.ToDictionary(r => r.Key, r => r.Value) : new Dictionary(),
TotalCapacity = new Dictionary(),
NonProjectTime = new Dictionary()
};
// fill resource model with actual data from the live database
if (backupCategory != null)
{
if (backupCategory.Resources != null &&
backupCategory.Resources.ContainsKey(resourceKey))
{
var backupResource = backupCategory.Resources[resourceKey];
serverResource.Teams = (backupResource.Teams != null) ?
backupResource.Teams.Clone() : new List();
if (backupResource.TotalCapacity != null)
serverResource.TotalCapacity = backupResource.TotalCapacity.Clone();
if (backupResource.NonProjectTime != null)
serverResource.NonProjectTime = backupResource.NonProjectTime.Clone();
if (backupResource.NonProjectTime != null)
serverResource.NonProjectTime = backupResource.NonProjectTime.Clone();
}
}
serverCategory.Resources.Add(resourceKey, serverResource);
}
}
// actual capacity should be calculated according to resource capacity
serverCategory.ActualCapacityValues = serverCategory.Resources
.SelectMany(x => x.Value.TotalCapacity)
.GroupBy(x => x.Key)
.ToDictionary(x => x.Key, g => g.Sum(s => s.Value));
if (backupCategory != null && backupCategory.PlannedCapacityValues != null)
serverCategory.PlannedCapacityValues = backupCategory.PlannedCapacityValues.Clone();
categories.Add(categoryKey, serverCategory);
}
}
serverTeamModel.ExpCategories = categories;
}
protected void MergeExpendituresNeedModel(MixCalendarModel serverCalendarModel, MixCalendarModel clientCalendarModel)
{
if ((clientCalendarModel == null) || (clientCalendarModel.Projects == null) || (clientCalendarModel.Projects.Keys.Count < 1))
// Client model has no projects data
return;
if ((serverCalendarModel.NeedAllocations == null) || (serverCalendarModel.NeedAllocations.Count < 1))
{
serverCalendarModel.NeedAllocations = clientCalendarModel.NeedAllocations;
return;
}
// Merge need data. When mix goes to mongo, scenarios internal data is force loaded to model.
// If mix was not ever saved, client model contains data for the only scenarios, whick were edited by user
foreach (var scenarioId in clientCalendarModel.NeedAllocations.Keys)
{
var clientScenarioData = clientCalendarModel.NeedAllocations[scenarioId];
if ((clientScenarioData != null) && (clientScenarioData.Expenditures != null) && (clientScenarioData.Expenditures.Count > 0))
{
if (!serverCalendarModel.NeedAllocations.ContainsKey(scenarioId))
serverCalendarModel.NeedAllocations.Add(scenarioId, clientScenarioData);
else
serverCalendarModel.NeedAllocations[scenarioId] = clientScenarioData;
}
}
}
protected void SortProjects(MixCalendarModel model, long startDateUnix, long endDateUnix)
{
model.ManagedProjects = new List();
model.UnscheduledProjects = new List();
model.QueuedProjects = new List();
model.UnassignedExpendituresProjects = new List();
if ((model.Projects == null) || (model.Projects.Count < 1))
return;
foreach (string projectIdText in model.Projects.Keys)
{
Guid projectId = new Guid(projectIdText);
MixProjectModel projectModel = model.Projects[projectIdText];
if (projectModel.Scenario == null)
{
// Send project to Unscheduled list
model.UnscheduledProjects.Add(projectId);
continue;
}
if ((projectModel.Scenario.StartDate > endDateUnix) ||
(projectModel.Scenario.EndDate < startDateUnix))
{
// Send project to Queued list
model.QueuedProjects.Add(projectId);
continue;
}
model.ManagedProjects.Add(projectId);
}
}
///
/// Merges collections of projects
///
/// Actual data taken from alive database
/// Mix data taken from Mongo
protected void MergeProjectLists(MixCalendarModel serverCalendarModel, MixCalendarModel clientCalendarModel)
{
if (serverCalendarModel == null)
throw new ArgumentException("serverCalendarModel");
if (serverCalendarModel.Projects == null)
throw new ArgumentException("serverCalendarModel.Projects");
if (serverCalendarModel.Teams == null)
throw new ArgumentException("serverCalendarModel.Teams");
if ((clientCalendarModel == null) || (clientCalendarModel.Projects == null))
return;
if (((clientCalendarModel.Projects == null) || (clientCalendarModel.Projects.Count < 1)) &&
(clientCalendarModel.ManagedProjects == null || (clientCalendarModel.ManagedProjects.Count < 1)) &&
((clientCalendarModel.UnscheduledProjects == null) || (clientCalendarModel.UnscheduledProjects.Count < 1)))
// Client model is empty
return;
foreach (var project in serverCalendarModel.Projects)
{
var mixProject = clientCalendarModel.Projects.FirstOrDefault(x => x.Value.Id == project.Value.Id);
if (mixProject.Value != null)
project.Value.Pinned = mixProject.Value.Pinned;
}
// All projects, found in live DB
var allLiveDbProjects = serverCalendarModel.Projects.Keys.Select(x => new Guid(x)).ToList();
// Merge Managed projects lists
List existingManagedProjects = clientCalendarModel.ManagedProjects.Where(p =>
serverCalendarModel.ManagedProjects.Contains(p)).ToList();
List newManagedProjectsFromServer = serverCalendarModel.ManagedProjects.Where(p =>
!existingManagedProjects.Contains(p) && !clientCalendarModel.UnscheduledProjects.Contains(p)).ToList();
serverCalendarModel.ManagedProjects.RemoveAll(p => !existingManagedProjects.Contains(p));
serverCalendarModel.ManagedProjects.AddRange(newManagedProjectsFromServer);
// Merge Unscheduled projects lists
List existingUnscheduledProjects = clientCalendarModel.UnscheduledProjects.Intersect(serverCalendarModel.UnscheduledProjects).ToList();
List clientOnlyUnscheduledProjects = clientCalendarModel.UnscheduledProjects.Except(serverCalendarModel.UnscheduledProjects)
.Where(x => allLiveDbProjects.Contains(x)).ToList();
List newUnscheduledProjectsFromServer = serverCalendarModel.UnscheduledProjects.Where(p =>
!existingUnscheduledProjects.Contains(p) &&
!serverCalendarModel.ManagedProjects.Contains(p)).ToList();
serverCalendarModel.UnscheduledProjects.RemoveAll(p => !existingUnscheduledProjects.Contains(p));
serverCalendarModel.UnscheduledProjects.AddRange(newUnscheduledProjectsFromServer); // Add recently added to live DB projects
serverCalendarModel.UnscheduledProjects.AddRange(clientOnlyUnscheduledProjects); // Add client only unscheduled projects (in live DB have teams and scenarios)
serverCalendarModel.QueuedProjects.RemoveAll(p => serverCalendarModel.ManagedProjects.Contains(p) ||
serverCalendarModel.UnscheduledProjects.Contains(p));
// Merge Unassigned Expenditures Projects
List existingUnassignedExpProjects = clientCalendarModel.UnassignedExpendituresProjects.Where(p =>
serverCalendarModel.ManagedProjects.Contains(p.ProjectId)).ToList();
serverCalendarModel.UnassignedExpendituresProjects.Clear();
serverCalendarModel.UnassignedExpendituresProjects.AddRange(existingUnassignedExpProjects);
}
///
/// Creates list of projects, which attached to the Mix, but were deleted from Live DB
///
/// Server model (receives projects deleted list)
/// Client model to compare with
///
///
public void SetDeletedFromLiveDbProjects(MixSaveModel serverCalendarModel,
MixCalendarModel clientCalendarModel, DateTime filterStartDate, DateTime filterEndDate)
{
if ((serverCalendarModel == null) || (serverCalendarModel.Calendar == null) ||
(serverCalendarModel.Calendar.Projects == null) || (clientCalendarModel == null) ||
(clientCalendarModel.Projects == null))
return;
serverCalendarModel.Calendar.ModifiedObjects.DeletedProjects = null;
// SA. ENV-1246. Get list of projects, which exist in Mongo Mix, but no longer exist on server
List projectModelsToCheck = clientCalendarModel.Projects.Where(p =>
!clientCalendarModel.QueuedProjects.Contains(new Guid(p.Key)) &&
!serverCalendarModel.Calendar.Projects.Keys.Contains(p.Key))
.Select(x => x.Value).ToList();
if (projectModelsToCheck.Count > 0)
{
List modelTeams = serverCalendarModel.Calendar.Teams.Select(t => new Guid(t.Id)).ToList();
projectModelsToCheck.RemoveAll(x => !ProjectPassFilter(x, filterStartDate, filterEndDate, modelTeams));
}
if (projectModelsToCheck.Count > 0)
{
List projectsToCheck = projectModelsToCheck.Select(p => p.Id).ToList();
List existingProjectsInLiveDb = dbContext.Projects.Where(p => projectsToCheck.Contains(p.Id))
.Select(p => p.Id).ToList();
List notFoundInLiveDbProjects = projectsToCheck.Where(x => !existingProjectsInLiveDb.Contains(x)).ToList();
if (notFoundInLiveDbProjects.Count > 0)
{
serverCalendarModel.Calendar.ModifiedObjects.DeletedProjects = clientCalendarModel.Projects.Where(p =>
notFoundInLiveDbProjects.Contains(new Guid(p.Key))).Select(p => p.Value.Name).ToList();
}
}
}
///
/// Updates live DB scenario versions for scenarios in mix model according to given version info data
///
/// Mix model to update scenarios in
/// New scenarios version info
public static void SetScenarioVersions(MixSaveModel model, List versionInfo)
{
if ((model == null) || (model.Calendar == null) || (model.Calendar.Projects == null))
return;
if (versionInfo == null)
return;
var projectsToUpdate = versionInfo.Where(x => model.Calendar.Projects.ContainsKey(x.ProjectId.ToString()))
.Select(x => x.ProjectId.ToString()).ToList();
var versionInfoIndexed = versionInfo.ToDictionary(k => k.ProjectId.ToString(), v => v);
foreach (var projectIdAsText in projectsToUpdate)
{
var projectModel = model.Calendar.Projects[projectIdAsText];
var versionInfoForProject = versionInfoIndexed[projectIdAsText];
if ((projectModel != null) && (projectModel.Scenario != null) && (versionInfoForProject != null))
{
projectModel.Scenario.Id = versionInfoForProject.ScenarioId;
if (projectModel.Scenario.VersionInfo == null)
{
projectModel.Scenario.VersionInfo = new ItemVersionInfo();
}
projectModel.Scenario.VersionInfo.SourceVersion = versionInfoForProject.Timestamp;
projectModel.Scenario.VersionInfo.RmoVersion = 1;
}
}
}
protected void MergeLayouts(MixCalendarModel serverCalendarModel, MixCalendarModel clientCalendarModel)
{
if (serverCalendarModel == null)
throw new ArgumentException("serverCalendarModel");
if (serverCalendarModel.Projects == null)
throw new ArgumentException("serverCalendarModel.Projects");
if (serverCalendarModel.Teams == null)
throw new ArgumentException("serverCalendarModel.Teams");
if ((clientCalendarModel == null) || (clientCalendarModel.Projects == null) ||
(clientCalendarModel.Layout == null) || (clientCalendarModel.Layout.Count < 1))
return;
List layoutTeams = serverCalendarModel.Teams.Select(t => new Guid(t.Id)).ToList();
serverCalendarModel.Layout = new List();
foreach (Guid teamId in layoutTeams)
{
List existingForTeam = serverCalendarModel.ManagedProjects.Where(p =>
(serverCalendarModel.Projects[p.ToString()].Teams != null) &&
(serverCalendarModel.Projects[p.ToString()].Teams.Contains(teamId)) &&
(clientCalendarModel.Layout != null) &&
clientCalendarModel.Layout.Any(l => (l.TeamId.Equals(teamId) && l.ProjectId.Equals(p)))
).ToList();
List newForTeam = serverCalendarModel.ManagedProjects.Where(p =>
(serverCalendarModel.Projects[p.ToString()].Teams != null) &&
(serverCalendarModel.Projects[p.ToString()].Teams.Contains(teamId)) &&
!existingForTeam.Contains(p)
).ToList();
List teamLayoutRowsForExisingProjects =
clientCalendarModel.Layout.Where(l => l.TeamId.Equals(teamId) && existingForTeam.Contains(l.ProjectId))
.Select(r => new MixTeamLayoutRowItem()
{
TeamId = teamId,
Row = r.Row,
ProjectId = r.ProjectId,
Index = r.Index
}).OrderBy(o1 => o1.Row).ThenBy(o2 => o2.Index).ToList();
List teamLayoutRowsForNewProjects =
newForTeam.Select(pId => new MixTeamLayoutRowItem()
{
TeamId = teamId,
Row = -1,
ProjectId = pId,
Index = 0
}).ToList();
// Renum row numbers for result layout rows
int lastOldRowNum = -1;
int newRowNum = -1;
int newColNum = 0;
foreach (MixTeamLayoutRowItem currentLayoutRow in teamLayoutRowsForExisingProjects)
{
if (lastOldRowNum != currentLayoutRow.Row)
{
// Project is located at new line
lastOldRowNum = currentLayoutRow.Row;
newRowNum++;
newColNum = 0;
}
else
{
// Projects is located at the same line with the previous one
newColNum++;
}
currentLayoutRow.Row = newRowNum;
currentLayoutRow.Index = newColNum;
}
// Set row numbers for new project layout rows
foreach (MixTeamLayoutRowItem currentLayoutRow in teamLayoutRowsForNewProjects)
{
newRowNum++;
currentLayoutRow.Row = newRowNum;
currentLayoutRow.Index = 0;
}
serverCalendarModel.Layout.AddRange(teamLayoutRowsForExisingProjects);
serverCalendarModel.Layout.AddRange(teamLayoutRowsForNewProjects);
}
}
protected void MergeProjectVersions(MixProjectModel serverProject, MixProjectModel clientProject)
{
ItemVersionInfo versionInfo = new ItemVersionInfo
{
ChangedInMain = false,
ChangedInRmo = false,
RmoVersion = 1,
SourceVersion = null
};
if ((serverProject.Scenario != null) && (clientProject.Scenario == null))
{
// Recently added to the Mix project
if (serverProject.Scenario.VersionInfo != null)
{
versionInfo.SourceVersion = serverProject.Scenario.VersionInfo.SourceVersion;
versionInfo.ChangedInMain = true;
}
serverProject.Scenario.VersionInfo = versionInfo;
}
if ((serverProject.Scenario != null) && (clientProject.Scenario != null))
{
// Project with active scenarios exist in both databases
if (clientProject.Scenario.VersionInfo != null)
{
versionInfo.RmoVersion = clientProject.Scenario.VersionInfo.RmoVersion;
versionInfo.SourceVersion = clientProject.Scenario.VersionInfo.SourceVersion;
versionInfo.ChangedInRmo = versionInfo.RmoVersion > 1;
versionInfo.ChangedInMain =
!versionInfo.ChangedInRmo &&
((serverProject.Scenario.VersionInfo != null) &&
(
serverProject.Scenario.VersionInfo.SourceVersion.HasValue &&
clientProject.Scenario.VersionInfo.SourceVersion.HasValue &&
(serverProject.Scenario.VersionInfo.SourceVersion.Value !=
clientProject.Scenario.VersionInfo.SourceVersion.Value)
) ||
(serverProject.Scenario.VersionInfo.SourceVersion.HasValue &&
!clientProject.Scenario.VersionInfo.SourceVersion.HasValue
) ||
(!serverProject.Scenario.VersionInfo.SourceVersion.HasValue &&
clientProject.Scenario.VersionInfo.SourceVersion.HasValue
));
}
serverProject.Scenario = clientProject.Scenario.Clone();
serverProject.Scenario.VersionInfo = versionInfo;
}
if ((serverProject.Scenario == null) && (clientProject.Scenario != null))
{
// Project's active scenario was deleted from LiveDB or deactivated, while in the Mix
// this project still has scenario
if (clientProject.Scenario.VersionInfo != null)
{
versionInfo.RmoVersion = clientProject.Scenario.VersionInfo.RmoVersion;
versionInfo.SourceVersion = clientProject.Scenario.VersionInfo.SourceVersion;
versionInfo.ChangedInRmo = versionInfo.RmoVersion > 1;
versionInfo.ChangedInMain = !versionInfo.ChangedInRmo;
}
serverProject.Scenario = clientProject.Scenario.Clone();
serverProject.Scenario.VersionInfo = versionInfo;
}
}
///
/// Performs merging of info about scenario versions in server and cleint models
///
///
///
/// ItemVersionInfo struct for destination model ready-to-use
/// SA. ENV-1085
protected ItemVersionInfo MergeScenarioVersionData(ItemVersionInfo serverModel, ItemVersionInfo clientModel)
{
ItemVersionInfo result = new ItemVersionInfo();
if ((serverModel != null) && (clientModel != null))
{
result.SourceVersion = clientModel.SourceVersion.HasValue ?
clientModel.SourceVersion.Value : serverModel.SourceVersion;
result.RmoVersion = clientModel.RmoVersion;
result.ChangedInMain = serverModel.SourceVersion.HasValue && clientModel.SourceVersion.HasValue &&
(serverModel.SourceVersion != clientModel.SourceVersion);
result.ChangedInRmo = clientModel.RmoVersion > 1;
}
return result;
}
///
/// Returns TRUE, if project passes through Mix filter
///
/// Project to check
/// Filter start date
/// Filter end date
/// Filter teams
///
protected bool ProjectPassFilter(MixProjectModel projectModel, DateTime startDate, DateTime endDate,
List teams)
{
bool result = false;
if ((projectModel != null) && (projectModel.Teams != null) && (teams != null))
{
// We don't check dates, because, a project is included in a Mix, if it suits Mix filter teams.
// Dates only affect on projects sorting: Managed collection or Queued Projects
List commonTeams = projectModel.Teams.Intersect(teams).ToList();
return (commonTeams.Count > 0);
}
return result;
}
protected long GetUnixDate(DateTime? date)
{
return date.HasValue ? Utils.ConvertToUnixDate(date.Value) : 0;
}
}
}