1720 lines
82 KiB
JavaScript
1720 lines
82 KiB
JavaScript
'use strict';
|
|
|
|
app
|
|
.directive('optionClassExpr', function ($compile, $parse) {
|
|
var NG_OPTIONS_REGEXP = /^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+group\s+by\s+([\s\S]+?))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?$/;
|
|
|
|
return {
|
|
restrict: 'A',
|
|
link: function optionClassExprPostLink(scope, elem, attrs) {
|
|
var optionsExp = attrs.ngOptions;
|
|
if (!optionsExp) return;
|
|
|
|
var match = optionsExp.match(NG_OPTIONS_REGEXP);
|
|
if (!match) return;
|
|
|
|
var values = match[7];
|
|
|
|
scope.$watchCollection(function () {
|
|
return elem.children();
|
|
}, function (newValue) {
|
|
angular.forEach(newValue, function (child, index) {
|
|
var child = angular.element(child);
|
|
var val = child.val();
|
|
if (val) {
|
|
child.attr('ng-class', values + '[' + (index - 1) + '].' + attrs.optionClassExpr);
|
|
$compile(child)(scope);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
};
|
|
})
|
|
.directive('selectedSourceChanged', ['$timeout', function ($timeout) {
|
|
return {
|
|
link: function ($scope, element, attrs) {
|
|
$scope.$on('selectedSourceChanged', function () {
|
|
$timeout(function () { // You might need this timeout to be sure its run after DOM render.
|
|
element.trigger("change");
|
|
}, 0, false);
|
|
})
|
|
}
|
|
};
|
|
}])
|
|
.controller('capacityManagementController', ['$scope', '$http', '$location', '$timeout', '$window', 'cellHighligting', function ($scope, $http, $location, $timeout, $window, cellHighligting) {
|
|
$scope.CollapsedIcon = 'fa-plus-square';
|
|
$scope.NonCollapsedIcon = 'fa-minus-square';
|
|
|
|
$scope.ScenarioCollapsedIcon = 'fa-plus-square-1';
|
|
$scope.ScenarioNonCollapsedIcon = 'fa-minus-square-1';
|
|
|
|
$scope.ExpCatCollapsedIcon = 'fa-plus-square-2';
|
|
$scope.ExpCatNonCollapsedIcon = 'fa-minus-square-2';
|
|
|
|
$scope.id = $location.absUrl().substr($location.absUrl().lastIndexOf('ls/') + 3, 36);
|
|
//$scope.data = {
|
|
// VisibleCellCount: 1
|
|
//};
|
|
$scope.dataSection = "";
|
|
$scope.pageTitle = ""; // SA. ENV-905
|
|
$scope.preferences = [];
|
|
$scope.headerWidth = 70;
|
|
$scope.containerWidth = 0;
|
|
$scope.firstColWidth = 0;
|
|
|
|
|
|
$scope.calendarFilters = {
|
|
CompanyId: null,
|
|
StartDate: null,
|
|
EndDate: null,
|
|
ViewId: null,
|
|
TeamId: null,
|
|
ResourceId: null,
|
|
IsUOMHours: null,
|
|
PreferredTotalsDisplaying: null,
|
|
ShowUpper: true,
|
|
ShowLower: true,
|
|
IsBarMode: true,
|
|
ShowCapacity: 1, //"Total Allocated/Total Capacity"
|
|
GroupByTeam: true,
|
|
IsViewModeMonth: true,
|
|
ShowAvgTotals: true,
|
|
IsCapacityModeActuals: true,
|
|
sortOrder: false,
|
|
sortBy: 'Name'
|
|
};
|
|
|
|
// SA. ENV-799
|
|
$scope.CalendarFilterMode = {
|
|
IsCompany: true,
|
|
IsView: false,
|
|
IsTeam: false,
|
|
IsResource: false,
|
|
|
|
FilteredEntityTitle: "Company",
|
|
SelectedItemId: null,
|
|
}
|
|
|
|
$scope.SpreadType = {
|
|
Notspecified: -1,
|
|
Equal: 0,
|
|
Less: 1,
|
|
Over: 2
|
|
};
|
|
|
|
$scope.availableFilterOptions = {};
|
|
$scope.data = null;
|
|
$scope.data2Update = {
|
|
ChangedExpCats: []
|
|
};
|
|
|
|
$scope.grandtotalrow = null;
|
|
|
|
function getExpCatById(scenarioId, ExpCatId, teamId) {
|
|
for (var i = 0; i < $scope.data.Calendar.length; i++) {
|
|
if ($scope.data.Calendar[i].ExpCatId != null
|
|
&& $scope.data.Calendar[i].ScenarioId == scenarioId && $scope.data.Calendar[i].ExpCatId == ExpCatId &&
|
|
(!$scope.calendarFilters.GroupByTeam || $scope.data.Calendar[i].TeamId == teamId)) {
|
|
return $scope.data.Calendar[i];
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
function getRowByType(type, expCatId) {
|
|
for (var i = 0; i < $scope.data.Calendar.length; i++) {
|
|
if ($scope.data.Calendar[i].RowType == type) {
|
|
if (expCatId != null) {
|
|
if ($scope.data.Calendar[i].ExpCatId == expCatId)
|
|
return $scope.data.Calendar[i]; //return expCat by type+expCatId
|
|
} else
|
|
return $scope.data.Calendar[i]; //return expCat by type
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function getResourceById(resId) {
|
|
for (var i = 0; i < $scope.data.AllResources.length; i++) {
|
|
if ($scope.data.AllResources[i].Id == resId) {
|
|
return $scope.data.AllResources[i];
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
function getResourceByExpCat(expCat, resId) {
|
|
if (expCat != null) {
|
|
for (var i = 0; i < expCat.Resources.length; i++) {
|
|
|
|
if (expCat.Resources[i].Id == resId) {
|
|
return expCat.Resources[i];
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function setChildrenCollapsed(row, internal, parentCollapsed) {
|
|
|
|
var isProject = row.ProjectId != null && row.ExpCatId == null;
|
|
var isExpCat = row.ExpCatId != null;
|
|
|
|
for (var i = 0; i < $scope.data.Calendar.length; i++) {
|
|
var currRow = $scope.data.Calendar[i];
|
|
if (isProject && currRow.ExpCatId != null && currRow.ProjectId == row.ProjectId &&
|
|
(!$scope.calendarFilters.GroupByTeam || currRow.TeamId == row.TeamId)) {
|
|
var expCat = currRow;
|
|
if (internal) {
|
|
expCat.IsParentCollapsed = parentCollapsed;
|
|
setChildrenCollapsed(expCat, true, parentCollapsed);
|
|
} else {
|
|
expCat.IsParentCollapsed = row.ProjectCollapsed;
|
|
setChildrenCollapsed(expCat, true, row.ProjectCollapsed);
|
|
}
|
|
} else if (isExpCat && currRow.ExpCatId == row.ExpCatId && currRow.ScenarioId == row.ScenarioId &&
|
|
(!$scope.calendarFilters.GroupByTeam || currRow.TeamId == row.TeamId)) {
|
|
var resource = currRow;
|
|
if (internal) {
|
|
resource.IsParentCollapsed = parentCollapsed;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function clearResource(scenarioId, expCatId, resource, teamId) {
|
|
if (resource != null) {
|
|
for (var i = 0; i < $scope.data.Headers.length; i++) {
|
|
changeResourceValue(0, scenarioId, expCatId, resource.Id, teamId, i);
|
|
}
|
|
}
|
|
}
|
|
|
|
function updateTotals(expCat, expCatTotal, resourceTotal, resource, colIndex, newQuantity, oldQuantity, newCost, oldCost) {
|
|
var monthStartIndex = 0;
|
|
var monthEndIndex = colIndex;
|
|
var weeks = 0;
|
|
for (var i = colIndex + 1; i < $scope.data.Headers.length; i++) {
|
|
if (!$scope.data.Headers[i].IsMonth) {
|
|
monthEndIndex++;
|
|
} else {
|
|
weeks = $scope.data.Headers[i].Weeks.length;
|
|
monthStartIndex = monthEndIndex - weeks + 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
var total = 0;
|
|
var monthTotalCellIndex = monthEndIndex + 1;
|
|
oldQuantity = resource.QuantityValues[monthTotalCellIndex];
|
|
|
|
for (var i = monthStartIndex; i < monthTotalCellIndex; i++) {
|
|
if (colIndex == i)
|
|
total += newQuantity;
|
|
else
|
|
total += resource.QuantityValues[i];
|
|
}
|
|
|
|
if ($scope.calendarFilters.ShowAvgTotals && !$scope.calendarFilters.IsUOMHours) {
|
|
newQuantity = Math.round(total / weeks * 1000) / 1000;
|
|
} else {
|
|
//update month cell
|
|
//resource.QuantityValues[i] += (newQuantity - oldQuantity);
|
|
newQuantity = total;
|
|
}
|
|
|
|
resource.QuantityValues[monthTotalCellIndex] = newQuantity;
|
|
if (resourceTotal != null) {
|
|
resourceTotal.QuantityValues[monthTotalCellIndex] += (newQuantity - oldQuantity);
|
|
expCatTotal.QuantityValues[monthTotalCellIndex] += (newQuantity - oldQuantity);
|
|
}
|
|
recalcSpreading(expCat, expCatTotal, resourceTotal, monthTotalCellIndex);
|
|
updateCSSClass(expCat, resource, colIndex);
|
|
}
|
|
|
|
function GetAssignedResCount() {
|
|
var resIds = "";
|
|
var res = 0;
|
|
for (var i = 0; i < $scope.data.Calendar.length; i++) {
|
|
if ($scope.data.Calendar[i].ExpCatId != null && $scope.data.Calendar[i].ScenarioId != null) {
|
|
for (var j = 0; j < $scope.data.Calendar[i].Resources.length; j++) {
|
|
var resId = $scope.data.Calendar[i].Resources[j].Id;
|
|
if (resIds.indexOf(resId + ",") == -1) {
|
|
resIds += resId + ",";
|
|
res++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
function allocateResource(resource, expCat, create, allocateRest, reset) {
|
|
if (resource != null) {
|
|
|
|
var scenarioCalendarRow = null;
|
|
var i;
|
|
for (i = 0; i < $scope.data.Calendar.length; i++) {
|
|
if ($scope.data.Calendar[i].ExpCatId == expCat.ExpCatId && $scope.data.Calendar[i].ScenarioId == expCat.ScenarioId) {
|
|
scenarioCalendarRow = $scope.data.Calendar[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
var team = null;
|
|
for (i = 0; i < expCat.Teams.length; i++) {
|
|
if (expCat.Teams[i].Id == resource.TeamId) {
|
|
team = expCat.Teams[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
var res = getResourceById(resource.Id);
|
|
for (i = 0; i < $scope.data.Headers.length; i++) {
|
|
if ($scope.data.Headers[i].IsMonth || resource.ReadOnlyWeeks[i])
|
|
continue;
|
|
|
|
var needToAssign = Math.max(team.QuantityValues[i] - team.AllocatedByResources[i], 0);
|
|
var quantity = 0;
|
|
if (create || reset) //Reset
|
|
{
|
|
if (create)
|
|
resource.QuantityValues[i] = 0;
|
|
quantity = 0;
|
|
|
|
} else if (allocateRest) { //AssignRest
|
|
var canBeAssigned = Math.max(res.CapacityQuantityValues[i] - res.AllocatedQuantityValues[i], 0);
|
|
quantity = Math.min(needToAssign, canBeAssigned);
|
|
if (quantity == 0) {
|
|
continue;
|
|
}
|
|
quantity += resource.QuantityValues[i];
|
|
|
|
} else { //AssignAll
|
|
var canBeAssigned = Math.max(res.CapacityQuantityValues[i] - res.AllocatedQuantityValues[i], 0);
|
|
quantity = Math.min(needToAssign, canBeAssigned);
|
|
if (quantity == 0) {
|
|
continue;
|
|
}
|
|
quantity += resource.QuantityValues[i];
|
|
}
|
|
|
|
changeResourceValue(quantity, expCat.ScenarioId, expCat.ExpCatId, resource.Id, resource.TeamId, i);
|
|
}
|
|
}
|
|
}
|
|
|
|
function recalcSpreading(expCat, expCatTotal, resourceTotal, colIndex) {
|
|
var i;
|
|
if (expCat != null) {
|
|
var scenarioCalendarRow = null;
|
|
for (i = 0; i < $scope.data.Calendar.length; i++) {
|
|
if ($scope.data.Calendar[i].ProjectId == expCat.ProjectId && $scope.data.Calendar[i].ExpCatId == null
|
|
&& $scope.data.Calendar[i].ScenarioId == expCat.ScenarioId) {
|
|
scenarioCalendarRow = $scope.data.Calendar[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
var resTotal = 0;
|
|
for (i = 0; i < expCat.Resources.length; i++) {
|
|
resTotal += expCat.Resources[i].QuantityValues[colIndex];
|
|
}
|
|
|
|
//resTotal = Math.round(resTotal * 1000000) / 1000000;
|
|
|
|
var compareRes = cellHighligting.compare(resTotal, expCat.QuantityValues[colIndex]);
|
|
|
|
expCat.SpreadVal[colIndex] = compareRes > 0 ? $scope.SpreadType.Over :
|
|
compareRes < 0 ? $scope.SpreadType.Less :
|
|
compareRes == 0 ? $scope.SpreadType.Equal : $scope.SpreadType.Notspecified;
|
|
updateCSSClass(expCat, null, colIndex);
|
|
|
|
var projectClass = $scope.SpreadType.Equal;
|
|
for (i = 0; i < $scope.data.Calendar.length; i++) {
|
|
if ($scope.data.Calendar[i].ProjectId == expCat.ProjectId && $scope.data.Calendar[i].ExpCatId != null
|
|
&& $scope.data.Calendar[i].ScenarioId == expCat.ScenarioId && (!$scope.calendarFilters.GroupByTeam || $scope.data.Calendar[i].TeamId == expCat.TeamId)) {
|
|
if ($scope.data.Calendar[i].SpreadVal[colIndex] == $scope.SpreadType.Over) {
|
|
projectClass = $scope.SpreadType.Over;
|
|
break;
|
|
} else if ($scope.data.Calendar[i].SpreadVal[colIndex] == $scope.SpreadType.Less) {
|
|
projectClass = $scope.SpreadType.Less;
|
|
}
|
|
}
|
|
}
|
|
scenarioCalendarRow.SpreadVal[colIndex] = projectClass;
|
|
updateCSSClass(scenarioCalendarRow, null, colIndex);
|
|
}
|
|
|
|
//calc exp cat total row
|
|
if (expCatTotal != null) {
|
|
//var expCatSpread = $scope.SpreadType.Equal;
|
|
|
|
for (i = 0; i < expCatTotal.Resources.length; i++) {
|
|
var res = expCatTotal.Resources[i];
|
|
var resValue = res.QuantityTotalResValue[colIndex]; //expCatTotal.QuantityTotalResValue[colIndex];
|
|
var compareRes = cellHighligting.compare(res.QuantityValues[colIndex], resValue);
|
|
var compareResAndEc = cellHighligting.compare(res.QuantityValues[colIndex], expCatTotal.QuantityValues[colIndex]);
|
|
|
|
res.SpreadVal[colIndex] = compareRes > 0 ? $scope.SpreadType.Over :
|
|
compareRes < 0 ? $scope.SpreadType.Less :
|
|
compareRes == 0 ? $scope.SpreadType.Equal : $scope.SpreadType.Notspecified;
|
|
updateCSSClass(expCatTotal, res, colIndex);
|
|
}
|
|
if (expCat != null && expCat.Resources != null) {
|
|
for (i = 0; i < expCat.Resources.length; i++) {
|
|
var res = expCat.Resources[i];
|
|
var resValue = expCat.QuantityValues[colIndex];
|
|
var compareRes = cellHighligting.compare(res.QuantityValues[colIndex], resValue);
|
|
|
|
res.SpreadVal[colIndex] = compareRes > 0 ? $scope.SpreadType.Over :
|
|
compareRes < 0 ? $scope.SpreadType.Less :
|
|
compareRes == 0 ? $scope.SpreadType.Equal : $scope.SpreadType.Notspecified;
|
|
updateCSSClass(expCat, res, colIndex);
|
|
}
|
|
}
|
|
|
|
var resValue = expCatTotal.QuantityTotalResValue[colIndex];
|
|
var compareRes = cellHighligting.compare(expCatTotal.QuantityValues[colIndex], resValue);
|
|
expCatTotal.SpreadVal[colIndex] = compareRes > 0 ? $scope.SpreadType.Over :
|
|
compareRes < 0 ? $scope.SpreadType.Less :
|
|
compareRes == 0 ? $scope.SpreadType.Equal : $scope.SpreadType.Notspecified;
|
|
|
|
updateCSSClass(expCatTotal, null, colIndex);
|
|
}
|
|
}
|
|
|
|
function updateCSSClass(row, resRow, colIndex) {
|
|
if (resRow == null) { // updating project/scenario/category row
|
|
if (row == null || colIndex == null || row.SpreadVal == null || row.SpreadVal.length <= colIndex)
|
|
return;
|
|
row.CSSClass[colIndex] = (row.CSSClass[colIndex] || '').replace(/cellover/g, '').replace(/cellless/g, '').replace(/cellequal/g, '');;
|
|
if (!row.ReadOnly[colIndex]) {
|
|
if (row.SpreadVal[colIndex] == $scope.SpreadType.Equal)
|
|
row.CSSClass[colIndex] = 'cellequal';
|
|
else if (row.SpreadVal[colIndex] == $scope.SpreadType.Over)
|
|
row.CSSClass[colIndex] = 'cellover';
|
|
else if (row.SpreadVal[colIndex] == $scope.SpreadType.Less)
|
|
row.CSSClass[colIndex] = 'cellless';
|
|
|
|
if (row.RowType == 0) {
|
|
if (row.Color != null && row.Color.length > 0 && $scope.calendarFilters.IsBarMode) {
|
|
row.BarStyle[colIndex] = "border-bottom: 1px solid " + row.Color + " !important;border-right-color: " + row.Color + " !important;background-color: " + row.Color + ";";
|
|
} else {
|
|
row.BarStyle[colIndex] = null;
|
|
}
|
|
}
|
|
}
|
|
if ((row.ProjectId == null && row.ExpCatId != null && $scope.calendarFilters.ShowCapacity == 1) ||
|
|
(row.ProjectId == null && row.ExpCatId != null && $scope.calendarFilters.ShowCapacity == 2) ||
|
|
(row.ProjectId == null && row.ExpCatId != null && $scope.calendarFilters.ShowCapacity == 3))
|
|
row.CSSClass[colIndex] += ' capacity-total';
|
|
// assign more classes if needed
|
|
} else { // updating resource row
|
|
if (row == null || colIndex == null || row.ReadOnly[colIndex])
|
|
return;
|
|
|
|
if (resRow.SpreadVal == null || resRow.SpreadVal.length <= colIndex)
|
|
return;
|
|
resRow.CSSClass[colIndex] = (resRow.CSSClass[colIndex] || '').replace(/cellover/g, '').replace(/cellless/g, '').replace(/cellequal/g, '');;
|
|
if (resRow.SpreadVal[colIndex] == $scope.SpreadType.Equal)
|
|
resRow.CSSClass[colIndex] = 'cellequal';
|
|
else if (resRow.SpreadVal[colIndex] == $scope.SpreadType.Over)
|
|
resRow.CSSClass[colIndex] = 'cellover';
|
|
else if (resRow.SpreadVal[colIndex] == $scope.SpreadType.Less)
|
|
resRow.CSSClass[colIndex] = 'cellless';
|
|
// assign more classes if needed
|
|
}
|
|
}
|
|
|
|
function recalcRest(expCat, colIndex) {
|
|
var sum = 0;
|
|
for (var i = 0; i < expCat.Resources.length; i++) {
|
|
sum += expCat.Resources[i].QuantityValues[colIndex];
|
|
}
|
|
if (expCat.QuantityValues[colIndex] < sum)
|
|
expCat.RestQuantity[colIndex] = 0;
|
|
else
|
|
expCat.RestQuantity[colIndex] = expCat.QuantityValues[colIndex] - sum;
|
|
}
|
|
|
|
function changeResourceValue(newValue, scenarioId, expCatId, resId, teamId, colIndex) {
|
|
var expCat = getExpCatById(scenarioId, expCatId, teamId);
|
|
var expCatTotal = getExpCatById(null, expCatId, null);
|
|
var resource = getResourceByExpCat(expCat, resId);
|
|
var resourceTotal = getResourceByExpCat(expCatTotal, resId);
|
|
|
|
if (expCat != null && resource != null) {
|
|
|
|
var team = null;
|
|
for (var i = 0; i < expCat.Teams.length; i++) {
|
|
if (expCat.Teams[i].Id == resource.TeamId) {
|
|
team = expCat.Teams[i];
|
|
break;
|
|
}
|
|
}
|
|
var res = getResourceById(resource.Id);
|
|
|
|
team.AllocatedByResources[colIndex] += (newValue - resource.QuantityValues[colIndex]);
|
|
res.AllocatedQuantityValues[colIndex] += (newValue - resource.QuantityValues[colIndex]);
|
|
|
|
resource.GrandTotalQuantity += (newValue - resource.QuantityValues[colIndex]);
|
|
updateTotals(expCat, expCatTotal, resourceTotal, resource, colIndex, newValue, resource.QuantityValues[colIndex], 0, 0);
|
|
//expCat.RestQuantity[colIndex] -= newValue - resource.QuantityValues[colIndex];
|
|
|
|
|
|
if (expCatTotal != null && resourceTotal != null) {
|
|
resourceTotal.QuantityValues[colIndex] += (newValue - resource.QuantityValues[colIndex]);
|
|
expCatTotal.QuantityValues[colIndex] += (newValue - resource.QuantityValues[colIndex]);
|
|
}
|
|
resource.QuantityValues[colIndex] = newValue;
|
|
recalcRest(expCat, colIndex);
|
|
|
|
applyCellChange(scenarioId, expCatId, $scope.data.Headers[colIndex].Milliseconds, expCat.DetailIds[colIndex],
|
|
newValue, 0, resId, false, false);
|
|
}
|
|
recalcSpreading(expCat, expCatTotal, resourceTotal, colIndex);
|
|
updateCSSClass(expCat, resource, colIndex);
|
|
}
|
|
|
|
function applyCellChange(scenarioId, rowId, cellMilliseconds, cellId, cellQuantity, cellCost, resId, isAdded, isRemoved) {
|
|
var catIndex = -1;
|
|
for (var ix = 0; ix < $scope.data2Update.ChangedExpCats.length; ix++) {
|
|
if ($scope.data2Update.ChangedExpCats[ix].Id == rowId && $scope.data2Update.ChangedExpCats[ix].ScenarioId == scenarioId) {
|
|
catIndex = ix;
|
|
break;
|
|
}
|
|
}
|
|
if (catIndex == -1) {
|
|
$scope.data2Update.ChangedExpCats[$scope.data2Update.ChangedExpCats.length] = {
|
|
ScenarioId: scenarioId,
|
|
Id: rowId,
|
|
Values: [],
|
|
Resources: []
|
|
};
|
|
catIndex = $scope.data2Update.ChangedExpCats.length - 1;
|
|
}
|
|
|
|
if (resId == null) {
|
|
var dateIndex = -1;
|
|
for (var dx = 0; dx < $scope.data2Update.ChangedExpCats[catIndex].Values.length; dx++) {
|
|
if ($scope.data2Update.ChangedExpCats[catIndex].Values[dx].Id == cellId) {
|
|
dateIndex = dx;
|
|
break;
|
|
}
|
|
}
|
|
if (dateIndex == -1) {
|
|
$scope.data2Update.ChangedExpCats[catIndex].Values[$scope.data2Update.ChangedExpCats[catIndex].Values.length] = {
|
|
Id: cellId,
|
|
Milliseconds: cellMilliseconds,
|
|
Values: []
|
|
};
|
|
dateIndex = $scope.data2Update.ChangedExpCats[catIndex].Values.length - 1;
|
|
}
|
|
|
|
//$scope.data2Update.ChangedExpCats[catIndex].Values[dateIndex].Cost = cellCost;
|
|
$scope.data2Update.ChangedExpCats[catIndex].Values[dateIndex].Quantity = cellQuantity;
|
|
|
|
} else {
|
|
|
|
var dateIndex = -1;
|
|
for (var dx = 0; dx < $scope.data2Update.ChangedExpCats[catIndex].Resources.length; dx++) {
|
|
if ($scope.data2Update.ChangedExpCats[catIndex].Resources[dx].Id == resId) {
|
|
dateIndex = dx;
|
|
break;
|
|
}
|
|
}
|
|
if (dateIndex == -1) {
|
|
$scope.data2Update.ChangedExpCats[catIndex].Resources[$scope.data2Update.ChangedExpCats[catIndex].Resources.length] = {
|
|
Id: resId,
|
|
Values: [],
|
|
IsAdded: isAdded,
|
|
IsRemoved: isRemoved
|
|
};
|
|
dateIndex = $scope.data2Update.ChangedExpCats[catIndex].Resources.length - 1;
|
|
if (isAdded || isRemoved)
|
|
return;
|
|
} else {
|
|
if (isRemoved) {
|
|
if ($scope.data2Update.ChangedExpCats[catIndex].Resources[dateIndex].IsAdded) {
|
|
$scope.data2Update.ChangedExpCats[catIndex].Resources.splice(dateIndex, 1);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
var dateIndex1 = -1;
|
|
for (var dx = 0; dx < $scope.data2Update.ChangedExpCats[catIndex].Resources[dateIndex].Values.length; dx++) {
|
|
if ($scope.data2Update.ChangedExpCats[catIndex].Resources[dateIndex].Values[dx].Milliseconds == cellMilliseconds) {
|
|
dateIndex1 = dx;
|
|
break;
|
|
}
|
|
}
|
|
if (dateIndex1 == -1) {
|
|
$scope.data2Update.ChangedExpCats[catIndex].Resources[dateIndex].Values[$scope.data2Update.ChangedExpCats[catIndex].Resources[dateIndex].Values.length] = {
|
|
Id: cellId,
|
|
Milliseconds: cellMilliseconds,
|
|
Values: []
|
|
};
|
|
dateIndex1 = $scope.data2Update.ChangedExpCats[catIndex].Resources[dateIndex].Values.length - 1;
|
|
}
|
|
//$scope.data2Update.ChangedExpCats[catIndex].Resources[dateIndex].Values[dateIndex1].Cost = cellCost;
|
|
$scope.data2Update.ChangedExpCats[catIndex].Resources[dateIndex].Values[dateIndex1].Quantity = cellQuantity;
|
|
}
|
|
}
|
|
|
|
function refreshTotalSpreadVal(expCatTotal) {
|
|
if (expCatTotal.RowType == 7) {
|
|
for (var colIndex = 0; colIndex < $scope.data.Headers.length; colIndex++) {
|
|
var resValue = expCatTotal.QuantityTotalResValue[colIndex];
|
|
|
|
var total = 0;
|
|
var allocated = 0;
|
|
if ($scope.calendarFilters.ShowCapacity == 1) {
|
|
allocated = expCatTotal.QuantityValues[colIndex];
|
|
total = expCatTotal.QuantityTotalResValue[colIndex];
|
|
} else if ($scope.calendarFilters.ShowCapacity == 2) {
|
|
allocated = expCatTotal.QuantityExpCatTotalValue[colIndex];
|
|
total = expCatTotal.QuantityTotalResValue[colIndex];
|
|
} else {
|
|
allocated = expCatTotal.QuantityValues[colIndex];
|
|
total = expCatTotal.QuantityExpCatTotalValue[colIndex];
|
|
}
|
|
|
|
var compareRes = cellHighligting.compare(allocated, total);
|
|
|
|
expCatTotal.SpreadVal[colIndex] = compareRes > 0 ? $scope.SpreadType.Over :
|
|
compareRes < 0 ? $scope.SpreadType.Less :
|
|
compareRes == 0 ? $scope.SpreadType.Equal : $scope.SpreadType.Notspecified;
|
|
|
|
// this code sets Equal by default. It means that 2 zeros will be displayed as green
|
|
// so I decided to remove it to keep zeros without highligthing
|
|
//var expCatSpread = $scope.SpreadType.Equal;
|
|
//if (expCatTotal.SpreadVal[colIndex] == $scope.SpreadType.Over) {
|
|
// expCatSpread = $scope.SpreadType.Over;
|
|
//} else if (expCatTotal.SpreadVal[colIndex] == $scope.SpreadType.Less) {
|
|
// expCatSpread = $scope.SpreadType.Less;
|
|
//}
|
|
//expCatTotal.SpreadVal[colIndex] = expCatSpread;
|
|
|
|
updateCSSClass(expCatTotal, null, colIndex);
|
|
}
|
|
}
|
|
//updateCSSClass(expCatTotal, null, colIndex);
|
|
}
|
|
function initCmMenuItems() {
|
|
var menu = $('#' + $scope.calendarFilters.MenuId);
|
|
menu.html("");
|
|
|
|
$.each($("#menuCalendarOptionsPrint li"), function (i, o) {
|
|
$(o).appendTo(menu);
|
|
});
|
|
|
|
$.each($("#menuCalendarOptions li"), function (i, o) {
|
|
$(o).clone(true).appendTo(menu).change(function () {
|
|
if (typeof onCMPreferencesItemClick === 'function')
|
|
onCMPreferencesItemClick(menu);
|
|
});
|
|
});
|
|
|
|
// SA. ENV-815
|
|
$("#menuCalendarOptions").find('*[data-key]').removeAttr('data-key');
|
|
}
|
|
|
|
$scope.init = function (initData) {
|
|
$scope.calendarFilters.ShowUpper = initData.ShowUpper;
|
|
$scope.calendarFilters.ShowLower = initData.ShowLower;
|
|
$scope.calendarFilters.IsUOMHours = initData.IsUOMHours;
|
|
$scope.calendarFilters.PreferredTotalsDisplaying = initData.PreferredTotalsDisplaying;
|
|
$scope.calendarFilters.IsBarMode = initData.IsBarMode;
|
|
$scope.calendarFilters.IsViewModeMonth = initData.IsViewModeMonth;
|
|
$scope.calendarFilters.IsCapacityModeActuals = initData.IsCapacityModeActuals;
|
|
$scope.calendarFilters.GroupByTeam = initData.GroupByTeam;
|
|
$scope.calendarFilters.ShowCapacity = initData.ShowCapacity;
|
|
$scope.calendarFilters.StartDate = initData.StartDate;
|
|
$scope.calendarFilters.EndDate = initData.EndDate;
|
|
$scope.calendarFilters.ModelType = initData.ModelType;
|
|
$scope.calendarFilters.MenuId = initData.MenuId;
|
|
$scope.dataSection = initData.DataSection;
|
|
$scope.pageTitle = initData.PageTitle; // SA. ENV-905
|
|
$scope.availableFilterOptions = initData.FilterOptions; // SA. ENV-799
|
|
initCmMenuItems();
|
|
var pagePrefArray;
|
|
|
|
if (initData.PagePreferences && initData.PagePreferences.length > 0) {
|
|
// SA. ENV-799
|
|
var filterModeInit = "";
|
|
var filterSelectedItemId = null;
|
|
|
|
pagePrefArray = JSON.parse(initData.PagePreferences);
|
|
$scope.preferences = pagePrefArray;
|
|
|
|
for (var i = 0; i < pagePrefArray.length; i++) {
|
|
switch (pagePrefArray[i].Key) {
|
|
case "showChart":
|
|
$scope.calendarFilters.ShowUpper = pagePrefArray[i].Value;
|
|
break;
|
|
case "showCriteria":
|
|
$scope.calendarFilters.ShowLower = pagePrefArray[i].Value;
|
|
break;
|
|
case "showOption":
|
|
$scope.calendarFilters.ShowCapacity = pagePrefArray[i].Value != null ? pagePrefArray[i].Value : 1; //"Total Allocated/Total Need";
|
|
break;
|
|
case "uomMode":
|
|
$scope.calendarFilters.IsUOMHours = pagePrefArray[i].Value;
|
|
break;
|
|
case "capBarMode":
|
|
$scope.calendarFilters.IsBarMode = pagePrefArray[i].Value;
|
|
break;
|
|
case "defaultView":
|
|
$scope.calendarFilters.IsViewModeMonth = pagePrefArray[i].Value;
|
|
break;
|
|
case "groupByTeam":
|
|
if ($scope.calendarFilters.ModelType != 'TeamboardModel')
|
|
$scope.calendarFilters.GroupByTeam = pagePrefArray[i].Value;
|
|
else
|
|
$scope.calendarFilters.GroupByTeam = false;
|
|
break;
|
|
case "capacityView":
|
|
$scope.calendarFilters.IsCapacityModeActuals = pagePrefArray[i].Value;
|
|
break;
|
|
case "capacityFilterStartDate":
|
|
$scope.calendarFilters.StartDate = pagePrefArray[i].Value;
|
|
break;
|
|
case "capacityFilterEndDate":
|
|
$scope.calendarFilters.EndDate = pagePrefArray[i].Value;
|
|
break;
|
|
|
|
case "filterCompanyList":
|
|
if ((pagePrefArray[i].Value) && (filterModeInit.length < 1))
|
|
filterModeInit = "Company";
|
|
break;
|
|
|
|
case "filterViewList":
|
|
if ((pagePrefArray[i].Value) && (filterModeInit.length < 1))
|
|
filterModeInit = "View";
|
|
break;
|
|
|
|
case "filterTeamList":
|
|
if ((pagePrefArray[i].Value) && (filterModeInit.length < 1))
|
|
filterModeInit = "Team";
|
|
break;
|
|
|
|
case "filteredCompany":
|
|
filterSelectedItemId = pagePrefArray[i].Value;
|
|
break;
|
|
|
|
case "sortBy":
|
|
$scope.calendarFilters.sortBy = pagePrefArray[i].Value;
|
|
break;
|
|
case "sortOrder":
|
|
$scope.calendarFilters.sortOrder = pagePrefArray[i].Value;
|
|
break;
|
|
|
|
default:
|
|
console.log("Restore page preferences (Activity calendar): data key not found in parsing loaded preferences (datakey=" +
|
|
pagePrefArray[i].Key + ", dataSection=" + $scope.dataSection + ")");
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
pagePrefArray = [];
|
|
pagePrefArray.push({ Key: "showChart", Value: $scope.calendarFilters.ShowUpper });
|
|
pagePrefArray.push({ Key: "showCriteria", Value: $scope.calendarFilters.ShowLower });
|
|
pagePrefArray.push({ Key: "sortBy", Value: $scope.calendarFilters.sortBy });
|
|
pagePrefArray.push({ Key: "sortOrder", Value: $scope.calendarFilters.sortOrder });
|
|
pagePrefArray.push({ Key: "showOption", Value: $scope.calendarFilters.ShowCapacity });
|
|
pagePrefArray.push({ Key: "uomMode", Value: $scope.calendarFilters.IsUOMHours });
|
|
pagePrefArray.push({ Key: "capBarMode", Value: $scope.calendarFilters.IsBarMode });
|
|
pagePrefArray.push({ Key: "defaultView", Value: $scope.calendarFilters.IsViewModeMonth });
|
|
pagePrefArray.push({ Key: "groupByTeam", Value: $scope.calendarFilters.GroupByTeam });
|
|
pagePrefArray.push({ Key: "capacityView", Value: $scope.calendarFilters.IsCapacityModeActuals });
|
|
pagePrefArray.push({ Key: "capacityFilterStartDate", Value: $scope.calendarFilters.StartDate });
|
|
pagePrefArray.push({ Key: "capacityFilterEndDate", Value: $scope.calendarFilters.EndDate });
|
|
// pagePrefArray.push({ Key: "filteredCompany", Value: $scope.calendarFilters.CompanyId });
|
|
|
|
restorePreferences($scope.dataSection, pagePrefArray);
|
|
|
|
$('#' + $scope.calendarFilters.MenuId).click(function (event) {
|
|
event.stopPropagation();
|
|
});
|
|
|
|
// SA. ENV-799
|
|
if ($scope.IsEmpty(initData.CompanyId) && $scope.IsEmpty(initData.ViewId) &&
|
|
$scope.IsEmpty(initData.TeamId) && $scope.IsEmpty(initData.ResourceId)) {
|
|
if (filterModeInit == "Company")
|
|
initData.CompanyId = filterSelectedItemId;
|
|
|
|
if (filterModeInit == "View")
|
|
initData.ViewId = filterSelectedItemId;
|
|
|
|
if (filterModeInit == "Team")
|
|
initData.TeamId = filterSelectedItemId;
|
|
|
|
if (filterModeInit == "Resource")
|
|
initData.ResourceId = filterSelectedItemId;
|
|
}
|
|
|
|
var filterAttached = false;
|
|
|
|
// if ($scope.calendarFilters.ModelType && ($scope.calendarFilters.ModelType == "EnVisage.Models.CapacityDetailsModel")) {
|
|
if (initData.CompanyId && (initData.CompanyId.length > 0)) {
|
|
$scope.CalendarFilterMode.SelectedItemId = initData.CompanyId;
|
|
$scope.switchCompanyFilterMode(true);
|
|
filterAttached = true;
|
|
}
|
|
|
|
if (initData.ViewId && (initData.ViewId.length > 0)) {
|
|
$scope.CalendarFilterMode.SelectedItemId = initData.ViewId;
|
|
$scope.switchViewFilterMode(true);
|
|
filterAttached = true;
|
|
|
|
}
|
|
|
|
if (initData.TeamId && (initData.TeamId.length > 0)) {
|
|
$scope.CalendarFilterMode.SelectedItemId = initData.TeamId;
|
|
$scope.switchTeamFilterMode(true);
|
|
filterAttached = true;
|
|
}
|
|
|
|
if (initData.ResourceId && (initData.ResourceId.length > 0)) {
|
|
$scope.CalendarFilterMode.SelectedItemId = initData.ResourceId;
|
|
$scope.switchResourceFilterMode(true);
|
|
filterAttached = true;
|
|
}
|
|
|
|
if (!filterAttached) {
|
|
$scope.switchCompanyFilterMode();
|
|
}
|
|
// }
|
|
|
|
// SA. ENV-799
|
|
$scope.loadCalendarData();
|
|
};
|
|
|
|
$scope.IsEmpty = function (value) {
|
|
return !value || (value == null) || (value == "");
|
|
}
|
|
|
|
$scope.getCalendar = function () {
|
|
$("#loader").hide();
|
|
|
|
if ($scope.IsEmpty($scope.calendarFilters.CompanyId) && $scope.IsEmpty($scope.calendarFilters.TeamId) &&
|
|
$scope.IsEmpty($scope.calendarFilters.ViewId) && $scope.IsEmpty($scope.calendarFilters.ResourceId)) {
|
|
return;
|
|
}
|
|
blockUI();
|
|
$scope.data = null;
|
|
$("#loader").show();
|
|
var postData = JSON.parse(JSON.stringify($scope.calendarFilters));
|
|
$http.post('/CapacityManagement/LoadJsonCalendar', postData).
|
|
success(function (data, status, headers, config) {
|
|
if (data == null)
|
|
$("#loader").hide();
|
|
if (data != null && data.Headers == null || data.Headers.length < 1) {
|
|
$("#loader").hide();
|
|
unblockUI();
|
|
return;
|
|
}
|
|
|
|
$scope.data = data;
|
|
$scope.calendarFilters.ShowAvgTotals = data.PreferredTotalsDisplaying;
|
|
$scope.calendarFilters.IsUOMHours = data.IsUOMHours;
|
|
swithViewMode();
|
|
|
|
for (var i = 0; i < $scope.data.Calendar.length; i++) {
|
|
$scope.data.Calendar[i].IsUpperHidden = !$scope.calendarFilters.ShowUpper;
|
|
$scope.data.Calendar[i].IsLowerHidden = !$scope.calendarFilters.ShowLower;
|
|
}
|
|
// initial setup css classes
|
|
for (var rowIndex = 0; rowIndex < $scope.data.Calendar.length; rowIndex++) {
|
|
if ($scope.data.Calendar[rowIndex].CSSClass == null)
|
|
$scope.data.Calendar[rowIndex].CSSClass = new Array($scope.data.Headers.length);
|
|
if ($scope.data.Calendar[rowIndex].BarStyle == null)
|
|
$scope.data.Calendar[rowIndex].BarStyle = new Array($scope.data.Headers.length);
|
|
refreshTotalSpreadVal($scope.data.Calendar[rowIndex]);
|
|
for (var colIndex = 0; colIndex < $scope.data.Headers.length; colIndex++) {
|
|
if ($scope.data.Calendar[rowIndex].RowType != 7)
|
|
updateCSSClass($scope.data.Calendar[rowIndex], null, colIndex);
|
|
|
|
if ($scope.data.Calendar[rowIndex].Resources != null && $scope.data.Calendar[rowIndex].Resources.length > 0) {
|
|
for (var resIndex = 0; resIndex < $scope.data.Calendar[rowIndex].Resources.length; resIndex++) {
|
|
if ($scope.data.Calendar[rowIndex].Resources[resIndex].CSSClass == null)
|
|
$scope.data.Calendar[rowIndex].Resources[resIndex].CSSClass = new Array($scope.data.Headers.length);
|
|
updateCSSClass($scope.data.Calendar[rowIndex], $scope.data.Calendar[rowIndex].Resources[resIndex], colIndex);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
for (i = 0; i < $scope.data.Calendar.length; i++) {
|
|
if ($scope.data.Calendar[i].IsTotals && $scope.data.Calendar[i].RowType == 5) {
|
|
$scope.grandtotalrow = $scope.data.Calendar[i];
|
|
break;
|
|
}
|
|
}
|
|
$("#loader").hide();
|
|
unblockUI();
|
|
}).
|
|
error(function (data, status, headers, config) {
|
|
// called asynchronously if an error occurs
|
|
// or server returns response with an error status.
|
|
console.log("an error occurred while loading calendar");
|
|
$("#loader").hide();
|
|
unblockUI();
|
|
});
|
|
};
|
|
$scope.checkEditable = function (useType) {
|
|
if (3 === useType) {
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
$scope.watchKeyInput = function (t) {
|
|
$timeout(function () {
|
|
if (t.$editable.inputEl.select)
|
|
t.$editable.inputEl.select();
|
|
else if (t.$editable.inputEl.setSelectionRange)
|
|
t.$editable.inputEl.setSelectionRange(0, t.$editable.inputEl.val().length);
|
|
}, 3);
|
|
|
|
t.$editable.inputEl.on('keydown', function (e) {
|
|
if (e.which == 9) { //when tab key is pressed
|
|
e.preventDefault();
|
|
var tab2Cell;
|
|
if (e.shiftKey) { // when shift + tab use with 'onblur' set to 'submit' for automatic submission find the parent of the editable before this one in the markup grab the editable and display it
|
|
tab2Cell = $(this).parentsUntil('table#table').prevAll(":has(.editable:visible):first").find(".editable:visible:last");
|
|
t.$form.$submit();
|
|
tab2Cell.click();
|
|
} else { // when just tab use with 'onblur' set to 'submit' for automatic submission find the parent of the editable after this one in the markup grab the editable and display it
|
|
tab2Cell = $(this).parentsUntil('table#table').nextAll(":has(.editable:visible):first").find(".editable:visible:first");
|
|
t.$form.$submit();
|
|
tab2Cell.click();
|
|
}
|
|
}
|
|
});
|
|
};
|
|
$scope.onTxtBlur = function (txt) {
|
|
txt.$form.$submit();
|
|
};
|
|
$scope.saveChanges = function () {
|
|
blockUI();
|
|
var postData = JSON.parse(JSON.stringify($scope.data2Update));
|
|
postData.ScenarioFilters = $scope.calendarFilters;
|
|
$http.post('/CapacityManagement/SaveChanges', postData).
|
|
success(function (data, status, headers, config) {
|
|
$scope.data2Update = {
|
|
ScenarioId: $scope.id,
|
|
ChangedExpCats: []
|
|
};
|
|
// alert("data saved successfully");
|
|
//var tab = $("#uidemo-tabs-default-demo li.active a").attr("href");
|
|
//var retUrl = window.location.href;
|
|
//if (retUrl.indexOf("&tab=") > 0) {
|
|
// retUrl = retUrl.substr(0, retUrl.indexOf("&tab="));
|
|
//}
|
|
//window.location.href = retUrl; // + "&tab=" + tab.replace("#", "");
|
|
$scope.getCalendar();
|
|
unblockUI();
|
|
}).
|
|
error(function (data, status, headers, config) {
|
|
console.log("an error occurred while saving calendar changes");
|
|
unblockUI();
|
|
});
|
|
};
|
|
$scope.takeAll = function (scenarioId, resId, expCatId, teamId) {
|
|
var expCat = getExpCatById(scenarioId, expCatId, teamId);
|
|
if (expCat != null) {
|
|
var create = false;
|
|
var allocateRest = false;
|
|
var reset = false;
|
|
allocateResource(getResourceByExpCat(expCat, resId), expCat, create, allocateRest, reset);
|
|
}
|
|
};
|
|
$scope.takeRemaining = function (scenarioId, resId, expCatId, teamId) {
|
|
var expCat = getExpCatById(scenarioId, expCatId, teamId);
|
|
if (expCat != null) {
|
|
var create = false;
|
|
var allocateRest = true;
|
|
var reset = false;
|
|
allocateResource(getResourceByExpCat(expCat, resId), expCat, create, allocateRest, reset); //false, true, false);
|
|
}
|
|
};
|
|
$scope.zeroResource = function (scenarioId, resId, expCatId, teamId) {
|
|
if (confirm("Are you sure you want fill this resource quantities with 0s?")) {
|
|
var expCat = getExpCatById(scenarioId, expCatId, teamId);
|
|
var create = false;
|
|
var allocateRest = false;
|
|
var reset = true;
|
|
allocateResource(getResourceByExpCat(expCat, resId), expCat, create, allocateRest, reset); //false, false, true);
|
|
}
|
|
};
|
|
$scope.assignResource = function (resId, scenarioId, expCatId, teamId, $event) {
|
|
if (resId == null || expCatId == null || teamId == null)
|
|
return;
|
|
|
|
var resource = getResourceById(resId);
|
|
if (resource != null) {
|
|
|
|
var expCat = getExpCatById(scenarioId, expCatId, teamId);
|
|
var expCatTotal = getExpCatById(null, expCatId, null);
|
|
var rowCapacity = getRowByType(6);
|
|
var rowVacation = getRowByType(2);
|
|
var rowTraining = getRowByType(3);
|
|
//Check the same resource assignment
|
|
if (getResourceByExpCat(expCat, resource.Id) != null) {
|
|
alert("The " + resource.Name + " has been assigned to the " + expCat.Name);
|
|
return;
|
|
}
|
|
|
|
//Add exp cat resource
|
|
//todo: just added resources are not validated against capacity values
|
|
var newResource = {
|
|
'Id': resource.Id,
|
|
'Name': resource.Name,
|
|
'QuantityValues': new Array($scope.data.Headers.length),
|
|
'SpreadVal': new Array($scope.data.Headers.length),
|
|
'CSSClass': new Array($scope.data.Headers.length),
|
|
'CapacityQuantityValues': new Array($scope.data.Headers.length),
|
|
'AllocatedQuantityValues': new Array($scope.data.Headers.length),
|
|
'ReadOnlyWeeks': new Array($scope.data.Headers.length),
|
|
'TeamId': resource.TeamId
|
|
};
|
|
var i;
|
|
for (i = 0; i < newResource.QuantityValues.length; i++) {
|
|
if (isNaN(newResource.QuantityValues[i]))
|
|
newResource.QuantityValues[i] = 0;
|
|
}
|
|
expCat.Resources.push(newResource);
|
|
|
|
if (expCatTotal != null) {
|
|
var resourceTotal = getResourceByExpCat(expCatTotal, resource.Id);
|
|
var colIndex;
|
|
if (resourceTotal == null) {
|
|
//Add total exp cat resource
|
|
resourceTotal = {
|
|
'Id': resource.Id,
|
|
'Name': resource.Name,
|
|
'QuantityValues': new Array($scope.data.Headers.length),
|
|
'SpreadVal': new Array($scope.data.Headers.length),
|
|
'CSSClass': new Array($scope.data.Headers.length)
|
|
};
|
|
for (i = 0; i < resourceTotal.QuantityValues.length; i++) {
|
|
if (isNaN(resourceTotal.QuantityValues[i]))
|
|
resourceTotal.QuantityValues[i] = 0;
|
|
}
|
|
expCatTotal.QuantityTotalResValue = expCatTotal.QuantityResValue * (expCatTotal.Resources.length + 1);
|
|
expCatTotal.Resources.push(resourceTotal);
|
|
for (colIndex = 0; colIndex < $scope.data.Headers.length; colIndex++) {
|
|
if (rowCapacity != null) {
|
|
rowCapacity.QuantityValues[colIndex] += expCatTotal.QuantityResValue;
|
|
}
|
|
}
|
|
}
|
|
|
|
var monthVacation = 0;
|
|
var monthTraining = 0;
|
|
var assignedResCount = 1; //GetAssignedResCount();
|
|
for (colIndex = 0; colIndex < $scope.data.Headers.length; colIndex++) {
|
|
if (!$scope.data.Headers[colIndex].IsMonth) {
|
|
if (rowVacation != null) {
|
|
rowVacation.QuantityValues[colIndex] += resource.VacationQuantityValues[colIndex];
|
|
monthVacation += rowVacation.QuantityValues[colIndex];
|
|
}
|
|
if (rowTraining != null) {
|
|
rowTraining.QuantityValues[colIndex] += resource.TrainingQuantityValues[colIndex];
|
|
monthTraining += rowTraining.QuantityValues[colIndex];
|
|
}
|
|
newResource.CapacityQuantityValues[colIndex] = expCatTotal.QuantityResValue - resource.VacationQuantityValues[colIndex] - resource.TrainingQuantityValues[colIndex];
|
|
newResource.ReadOnlyWeeks[colIndex] = resource.ReadOnlyWeeks[colIndex];
|
|
|
|
} else {
|
|
if ($scope.calendarFilters.ShowAvgTotals && !$scope.calendarFilters.IsUOMHours) {
|
|
monthVacation = Math.round(monthVacation / $scope.data.Headers[colIndex].Weeks.length / assignedResCount * 1000) / 1000;
|
|
monthTraining = Math.round(monthTraining / $scope.data.Headers[colIndex].Weeks.length / assignedResCount * 1000) / 1000;
|
|
} else {
|
|
|
|
}
|
|
$scope.grandtotalrow.QuantityValues[colIndex] += -(rowVacation.QuantityValues[colIndex] + rowTraining.QuantityValues[colIndex]) +
|
|
monthVacation + monthTraining;
|
|
rowVacation.QuantityValues[colIndex] = monthVacation;
|
|
rowTraining.QuantityValues[colIndex] = monthTraining;
|
|
|
|
monthTraining = 0;
|
|
monthVacation = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
var create = true;
|
|
var allocateRest = false;
|
|
var reset = false;
|
|
allocateResource(newResource, expCat, create, allocateRest, reset); //true, false, false);
|
|
expCatTotal.EmptyScenario = expCatTotal.Resources.length == 0;
|
|
//todo: remove
|
|
var tr = $($event.target).parentsUntil('table').last().parent().find('thead tr:first');
|
|
console.log("tr: " + $(tr).html());
|
|
var thName = tr.find('th:eq(0)');
|
|
console.log("thName: " + $(thName).html());
|
|
newResource.width = thName.width() + 'px';
|
|
}
|
|
};
|
|
$scope.removeResource = function (scenarioId, resId, expCatId, teamId) {
|
|
if (confirm("Are you sure you want to remove this resource?")) {
|
|
var expCat = getExpCatById(scenarioId, expCatId, teamId);
|
|
var expCatTotal = getExpCatById(null, expCatId, null);
|
|
var rowVacation = getRowByType(2);
|
|
var rowTraining = getRowByType(3);
|
|
var resource = getResourceById(resId);
|
|
|
|
for (var i = 0; i < expCat.Resources.length; i++) {
|
|
if (expCat.Resources[i].Id == resId) {
|
|
for (var k = 0; k < expCat.QuantityValues.length; k++) {
|
|
//expCat.RestQuantity[k] += expCat.Resources[i].QuantityValues[k];
|
|
changeResourceValue(0, expCat.ScenarioId, expCat.ExpCatId, expCat.Resources[i].Id, expCat.Resources[i].TeamId, k);
|
|
}
|
|
expCat.Resources.splice(i, 1);
|
|
|
|
var monthVacation = 0;
|
|
var monthTraining = 0;
|
|
var assignedResCount = 1; //GetAssignedResCount();
|
|
for (var colIndex = 0; colIndex < $scope.data.Headers.length; colIndex++) {
|
|
if (!$scope.data.Headers[colIndex].IsMonth) {
|
|
if (rowVacation != null) {
|
|
rowVacation.QuantityValues[colIndex] += resource.VacationQuantityValues[colIndex];
|
|
monthVacation += rowVacation.QuantityValues[colIndex];
|
|
}
|
|
if (rowTraining != null) {
|
|
rowTraining.QuantityValues[colIndex] += resource.TrainingQuantityValues[colIndex];
|
|
monthTraining += rowTraining.QuantityValues[colIndex];
|
|
}
|
|
//newResource.CapacityQuantityValues[colIndex] = expCatTotal.QuantityResValue - resource.VacationQuantityValues[colIndex] - resource.TrainingQuantityValues[colIndex];
|
|
} else {
|
|
if ($scope.calendarFilters.ShowAvgTotals && !$scope.calendarFilters.IsUOMHours) {
|
|
monthVacation = Math.round(monthVacation / $scope.data.Headers[colIndex].Weeks.length / assignedResCount * 1000) / 1000;
|
|
monthTraining = Math.round(monthTraining / $scope.data.Headers[colIndex].Weeks.length / assignedResCount * 1000) / 1000;
|
|
} else {
|
|
//rowVacation.QuantityValues[colIndex] = monthVacation;
|
|
//rowTraining.QuantityValues[colIndex] = monthTraining;
|
|
}
|
|
|
|
$scope.grandtotalrow.QuantityValues[colIndex] += -(rowVacation.QuantityValues[colIndex] + rowTraining.QuantityValues[colIndex]) +
|
|
monthVacation + monthTraining;
|
|
rowVacation.QuantityValues[colIndex] = monthVacation;
|
|
rowTraining.QuantityValues[colIndex] = monthTraining;
|
|
|
|
monthTraining = 0;
|
|
monthVacation = 0;
|
|
}
|
|
}
|
|
|
|
|
|
applyCellChange(scenarioId, expCatId, 0, 0, 0, 0, resId, false, true);
|
|
expCatTotal.EmptyScenario = expCatTotal.Resources.length == 0;
|
|
for (var colIndex = 0; colIndex < $scope.data.Headers.length; colIndex++) {
|
|
if (rowVacation != null) {
|
|
rowVacation.QuantityValues[colIndex] -= resource.VacationQuantityValues[colIndex];
|
|
if (rowVacation.QuantityValues[colIndex] < 0)
|
|
rowVacation.QuantityValues[colIndex] = 0;
|
|
}
|
|
if (rowTraining != null) {
|
|
rowTraining.QuantityValues[colIndex] -= resource.TrainingQuantityValues[colIndex];
|
|
if (rowTraining.QuantityValues[colIndex] < 0)
|
|
rowTraining.QuantityValues[colIndex] = 0;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
$scope.checkResourceValue = function (data, scenarioId, expCatId, resId, teamId, colIndex) {
|
|
var newValue = parseFloat(data);
|
|
if (isNaN(newValue))
|
|
newValue = 0;
|
|
if (newValue < 0) {
|
|
return "Value should not be less than zero";
|
|
}
|
|
|
|
var expCat = getExpCatById(scenarioId, expCatId, teamId);
|
|
var resource = getResourceByExpCat(expCat, resId);
|
|
var isMonth = $scope.data.Headers[colIndex].IsMonth;
|
|
|
|
if (isMonth) {
|
|
var ec_val = resource.QuantityValues[colIndex];
|
|
var weeks = 0;
|
|
for (var j = colIndex - 1; j >= 0 && !$scope.data.Headers[j].IsMonth; j--) {
|
|
weeks++;
|
|
}
|
|
|
|
var oldValue = ec_val;
|
|
var avg = ($scope.calendarFilters.ShowAvgTotals && !$scope.calendarFilters.IsUOMHours);
|
|
var coef = avg ? (newValue / oldValue) : (ec_val > 0 ? newValue / ec_val : 1);
|
|
|
|
for (var j = colIndex - 1; j >= 0 && !$scope.data.Headers[j].IsMonth; j--) {
|
|
var val = avg ? (ec_val > 0 ? resource.QuantityValues[j] * coef : newValue)
|
|
: (ec_val > 0 ? resource.QuantityValues[j] * coef : newValue / weeks);
|
|
changeResourceValue(val, scenarioId, expCatId, resId, teamId, j);
|
|
}
|
|
//changeResourceValue(newValue, scenarioId, expCatId, resId, teamId, colIndex);
|
|
} else {
|
|
changeResourceValue(newValue, scenarioId, expCatId, resId, teamId, colIndex);
|
|
}
|
|
|
|
return false;
|
|
};
|
|
$scope.getExpCatResources = function (expCat) {
|
|
var resources = [];
|
|
for (var i = 0; i < $scope.data.AllResources.length; i++) {
|
|
if ($scope.data.AllResources[i].ExpedentureCategoryId == expCat.ExpCatId && $scope.data.AllResources[i].IsActiveEmployee) {
|
|
var isProjectFound = false;
|
|
for (var j = 0; j < $scope.data.AllResources[i].ProjectIds.length; j++) {
|
|
|
|
if ($scope.data.AllResources[i].ProjectIds[j] == expCat.ProjectId &&
|
|
(!$scope.calendarFilters.GroupByTeam || $scope.data.AllResources[i].TeamId == expCat.TeamId)) {
|
|
isProjectFound = true;
|
|
break;
|
|
}
|
|
}
|
|
if (isProjectFound) {
|
|
var isFound = false;
|
|
for (var j = 0; j < expCat.Resources.length; j++) {
|
|
if (expCat.Resources[j].Id == $scope.data.AllResources[i].Id &&
|
|
(!$scope.calendarFilters.GroupByTeam || expCat.Resources[j].TeamId == $scope.data.AllResources[i].TeamId)) {
|
|
isFound = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!isFound) {
|
|
for (var j = 0; j < resources.length; j++) {
|
|
if (resources[j].Id == $scope.data.AllResources[i].Id &&
|
|
(!$scope.calendarFilters.GroupByTeam || resources[j].TeamId == $scope.data.AllResources[i].TeamId)) {
|
|
isFound = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (!isFound && $scope.data.AllResources[i].AssignedToTeam) {
|
|
if ($scope.calendarFilters.ResourceId == null || $scope.data.AllResources[i].Id == $scope.calendarFilters.ResourceId)
|
|
resources.push($scope.data.AllResources[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return resources;
|
|
};
|
|
$scope.isTakeAllDisabled = function (expCat, res) {
|
|
for (var j = 0; j < expCat.Resources.length; j++) {
|
|
if (expCat.Resources[j].ReadOnly) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
|
|
$scope.hideCalendarPart = function (upper) {
|
|
if (upper)
|
|
$scope.calendarFilters.ShowUpper = !$scope.calendarFilters.ShowUpper;
|
|
else
|
|
$scope.calendarFilters.ShowLower = !$scope.calendarFilters.ShowLower;
|
|
|
|
if (upper && !$scope.calendarFilters.ShowUpper)
|
|
$("#showButtomMode").switcher('disable');
|
|
else
|
|
$("#showButtomMode").switcher('enable');
|
|
|
|
|
|
if (!upper && !$scope.calendarFilters.ShowLower)
|
|
$("#showTopMode").switcher('disable');
|
|
else
|
|
$("#showTopMode").switcher('enable');
|
|
|
|
if ($scope.data != null) {
|
|
for (var i = 0; i < $scope.data.Calendar.length; i++) {
|
|
$scope.data.Calendar[i].IsLowerHidden = !$scope.calendarFilters.ShowLower;
|
|
$scope.data.Calendar[i].IsUpperHidden = !$scope.calendarFilters.ShowUpper;
|
|
}
|
|
}
|
|
// force digest cycle as this method could being called from JS
|
|
$scope.$digest();
|
|
};
|
|
$scope.switchUOMMode = function (value) {
|
|
var newValue = value != null ? value : !$scope.calendarFilters.IsUOMHours;
|
|
$scope.calendarFilters.IsUOMHours = newValue;
|
|
$scope.getCalendar();
|
|
};
|
|
$scope.switchGroupByTeam = function (value) {
|
|
var newValue = value != null ? value : !$scope.calendarFilters.GroupByTeam;
|
|
$scope.calendarFilters.GroupByTeam = newValue;
|
|
$scope.getCalendar();
|
|
};
|
|
$scope.switchCapacityVew = function (value) {
|
|
var newValue = value != null ? value : !$scope.calendarFilters.IsCapacityModeActuals;
|
|
$scope.calendarFilters.IsCapacityModeActuals = newValue;
|
|
$scope.getCalendar();
|
|
};
|
|
$scope.switchViewMode = function (value) {
|
|
var newValue = value != null ? value : !$scope.calendarFilters.IsViewModeMonth;
|
|
$scope.calendarFilters.IsViewModeMonth = newValue;
|
|
|
|
swithViewMode();
|
|
// force digest cycle as this method could being called from JS
|
|
$scope.$digest();
|
|
};
|
|
function swithViewMode() {
|
|
if (!$scope.data)
|
|
return;
|
|
var newValue = $scope.calendarFilters.IsViewModeMonth;
|
|
var j;
|
|
for (j = 0; j < $scope.data.YearHeaders.length; j++) {
|
|
|
|
$scope.data.YearHeaders[j].SpanCount = 0;
|
|
}
|
|
|
|
for (var i = 0; i < $scope.data.Headers.length; i++) {
|
|
var header = $scope.data.Headers[i];
|
|
if (header.IsMonth) {
|
|
header.Collapsed = newValue;
|
|
header.Show = newValue;
|
|
header.CollapsedClass = newValue ? $scope.CollapsedIcon : $scope.NonCollapsedIcon;
|
|
|
|
for (j = 0; j < $scope.data.YearHeaders.length; j++) {
|
|
if ($scope.data.YearHeaders[j].Title == header.Year) {
|
|
if (newValue) {
|
|
$scope.data.YearHeaders[j].SpanCount++; // -= header.Weeks.length - 1;
|
|
} else {
|
|
$scope.data.YearHeaders[j].SpanCount += header.Weeks.length;
|
|
}
|
|
//break;
|
|
}
|
|
}
|
|
|
|
} else {
|
|
header.Collapsed = newValue;
|
|
header.Show = !newValue;
|
|
}
|
|
header.Initialized = header.Initialized || header.Show;
|
|
}
|
|
getVisibleCellCount();
|
|
}
|
|
function getVisibleCellCount() {
|
|
var count = 0;
|
|
for (var i = 0; i < $scope.data.Headers.length; i++) {
|
|
var header = $scope.data.Headers[i];
|
|
if (header.Show)
|
|
count++;
|
|
}
|
|
$scope.data.VisibleCellCount = count;
|
|
}
|
|
$scope.switchBarMode = function () {
|
|
var newValue = !$scope.calendarFilters.IsBarMode;
|
|
$scope.calendarFilters.IsBarMode = newValue;
|
|
if (!$scope.data)
|
|
return;
|
|
|
|
// update project rows CSS
|
|
for (var rowIndex = 0; rowIndex < $scope.data.Calendar.length; rowIndex++) {
|
|
if ($scope.data.Calendar[rowIndex].RowType == 0)
|
|
for (var colIndex = 0; colIndex < $scope.data.Headers.length; colIndex++) {
|
|
updateCSSClass($scope.data.Calendar[rowIndex], null, colIndex);
|
|
}
|
|
}
|
|
// force digest cycle as this method could being called from JS
|
|
$scope.$digest();
|
|
};
|
|
$scope.changeCapacity = function (value) {
|
|
$scope.calendarFilters.ShowCapacity = value;
|
|
if (!$scope.data)
|
|
return;
|
|
|
|
for (var i = 0; i < $scope.data.Calendar.length; i++) {
|
|
if ($scope.data.Calendar[i].RowType == 7) {
|
|
var expCatTotal = $scope.data.Calendar[i];
|
|
refreshTotalSpreadVal(expCatTotal);
|
|
}
|
|
}
|
|
// force digest cycle as this method could being called from JS
|
|
$scope.$digest();
|
|
};
|
|
|
|
$scope.changeSortBy = function (value) {
|
|
$scope.calendarFilters.sortBy = value;
|
|
$scope.getCalendar();
|
|
};
|
|
$scope.switchSortOrder = function () {
|
|
var newValue = !$scope.calendarFilters.sortOrder;
|
|
$scope.calendarFilters.sortOrder = newValue;
|
|
$scope.getCalendar();
|
|
};
|
|
|
|
$scope.onMonthHeaderClick = function (header) {
|
|
header.Collapsed = !header.Collapsed;
|
|
header.Show = !header.Show;
|
|
header.CollapsedClass = header.Collapsed ? $scope.CollapsedIcon : $scope.NonCollapsedIcon;
|
|
header.Initialized = header.Initialized || header.Show;
|
|
var i;
|
|
if (header.Weeks && header.Weeks.length > 0)
|
|
for (i = 0; i < header.Weeks.length; i++) {
|
|
$scope.data.Headers[header.Weeks[i]].Collapsed = header.Collapsed;
|
|
$scope.data.Headers[header.Weeks[i]].Show = !header.Collapsed;
|
|
$scope.data.Headers[header.Weeks[i]].Initialized = $scope.data.Headers[header.Weeks[i]].Initialized || $scope.data.Headers[header.Weeks[i]].Show;
|
|
}
|
|
for (i = 0; i < $scope.data.YearHeaders.length; i++) {
|
|
if ($scope.data.YearHeaders[i].Title == header.Year) {
|
|
if (header.Collapsed) {
|
|
$scope.data.YearHeaders[i].SpanCount -= header.Weeks.length - 1;
|
|
} else {
|
|
$scope.data.YearHeaders[i].SpanCount += header.Weeks.length - 1;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
getVisibleCellCount();
|
|
$scope.onResize();
|
|
};
|
|
|
|
$scope.anyUpdated = function () {
|
|
return ($scope.data2Update && $scope.data2Update.ChangedExpCats && $scope.data2Update.ChangedExpCats.length > 0);
|
|
};
|
|
$scope.onParentNodeClick = function (row, $event) {
|
|
if ($($event.target).parents('.scenario-name').length > 0 || $($event.target).parents('.menuGroup').length > 0)
|
|
return;
|
|
if (row.ProjectId != null && row.ExpCatId == null) {
|
|
row.ProjectCollapsed = !row.ProjectCollapsed;
|
|
row.CollapsedClass = row.ProjectCollapsed ? $scope.CollapsedIcon : $scope.NonCollapsedIcon;
|
|
} else if (row.ExpCatId != null) {
|
|
row.ExpCatCollapsed = !row.ExpCatCollapsed;
|
|
if (row.ScenarioId != null)
|
|
row.CollapsedClass = row.ExpCatCollapsed ? $scope.ExpCatCollapsedIcon : $scope.ExpCatNonCollapsedIcon;
|
|
else
|
|
row.CollapsedClass = row.ExpCatCollapsed ? $scope.CollapsedIcon : $scope.NonCollapsedIcon;
|
|
}
|
|
//else if (row.ExpCatId == null) {
|
|
// row.ScenarioCollapsed = !row.ScenarioCollapsed;
|
|
// row.CollapsedClass = row.ScenarioCollapsed ? $scope.ScenarioCollapsedIcon : $scope.ScenarioNonCollapsedIcon;
|
|
//}
|
|
|
|
setChildrenCollapsed(row, false, row.IsParentCollapsed);
|
|
//$scope.onResize();
|
|
};
|
|
$scope.CheckLock = function ($event, tableId, fieldId, url) {
|
|
if (CheckLock(getEventTargetId($event), tableId, fieldId)) {
|
|
// SA. ENV-905. Added backurl to navigation link
|
|
var currentUrl = document.location.pathname + document.location.search;
|
|
var backUrl = "backUrl=" + encodeURIComponent(currentUrl);
|
|
var backName = "";
|
|
var navigateToUrl = url + '/' + fieldId + "?" + backUrl;
|
|
|
|
if ($scope.pageTitle && ($scope.pageTitle.length > 0))
|
|
// SA. The title of the page to return. Used to display in scenario form button
|
|
backName = "&backName=" + encodeURIComponent($scope.pageTitle);
|
|
|
|
var navigateToUrl = url + '/' + fieldId + "?" + backUrl + backName;
|
|
document.location.href = navigateToUrl;
|
|
}
|
|
};
|
|
$scope.ToggleStatus = function ($event, tableId, fieldId) {
|
|
if (CheckLock(getEventTargetId($event), tableId, fieldId)) {
|
|
if (fieldId == null || fieldId == "")
|
|
return "";
|
|
var url = "/ForecastDashboard/CheckIfActive/";
|
|
var request = {
|
|
'scenarioId': fieldId
|
|
};
|
|
$.get(url, request, function (data) {
|
|
if (data == null || data == "") {
|
|
$scope.ToggleStatusConfirmed(fieldId);
|
|
return '';
|
|
} else {
|
|
bootbox.confirm({
|
|
message: "There is an active scenario for this project already. Are you sure you want to activate this scenario instead of active one?",
|
|
callback: function (result) {
|
|
if (result) {
|
|
$scope.ToggleStatusConfirmed(fieldId);
|
|
}
|
|
},
|
|
className: "bootbox-sm"
|
|
});
|
|
}
|
|
});
|
|
}
|
|
};
|
|
$scope.ToggleStatusConfirmed = function (scenarioId) {
|
|
if (scenarioId == null || scenarioId == "")
|
|
return "";
|
|
var url = "/ForecastDashboard/ToggleStatus/";
|
|
var request = {
|
|
'scenarioId': scenarioId
|
|
};
|
|
$.get(url, request, function (data) {
|
|
$scope.getCalendar();
|
|
});
|
|
return '';
|
|
};
|
|
$scope.CalcRemainingCapacity = function (capacity, index) {
|
|
//for (var i = 0; i < $scope.data.Calendar.length; i++) {
|
|
// if ($scope.data.Calendar[i].IsTotals && $scope.data.Calendar[i].RowType == 5) {
|
|
// $scope.grandtotalrow = $scope.data.Calendar[i];
|
|
// break;
|
|
// }
|
|
//}
|
|
|
|
return (capacity - $scope.grandtotalrow.QuantityValues[index]); // - $scope.vacationrow.QuantityValues[index] - $scope.trainingrow.QuantityValues[index]);
|
|
};
|
|
$scope.CopyScenario = function ($event, scenarioId) {
|
|
if (CheckLock(getEventTargetId($event), 'Scenario', scenarioId)) {
|
|
if (scenarioId == null || scenarioId == "")
|
|
return "";
|
|
var url = "/Scenarios/Details/" + scenarioId + '?ptab=copy';
|
|
var backUrl = '&backUrl=' + encodeURIComponent('/CapacityManagement');
|
|
if (!!$scope.calendarFilters.TeamId)
|
|
backUrl = '&backUrl=' + encodeURIComponent('/Team/Board?ptab=calendar');
|
|
else if (!!$scope.calendarFilters.ViewId)
|
|
backUrl = '&backUrl=' + encodeURIComponent('/View/Board?ptab=calendar');
|
|
document.location.href = url; //+backUrl;
|
|
}
|
|
};
|
|
$scope.AddScenario = function ($event, projectId) {
|
|
if (typeof loadScenario === 'function')
|
|
loadScenario(projectId);
|
|
};
|
|
|
|
function getEventTargetId($event) {
|
|
if (!$event.target.id || $event.target.id === '')
|
|
return $event.target.parentElement.id;
|
|
|
|
return $event.target.id;
|
|
}
|
|
|
|
$scope.SelectedFilterElementChanged = function () {
|
|
if ($scope.CalendarFilterMode.SelectedItemId && ($scope.CalendarFilterMode.SelectedItemId.length > 0)) {
|
|
if ($scope.dataSection && ($scope.dataSection.length > 0)) {
|
|
var prefs = collectPreferences($scope.dataSection);
|
|
|
|
prefs.push({
|
|
Key: "filteredCompany",
|
|
Value: $scope.CalendarFilterMode.SelectedItemId
|
|
});
|
|
|
|
saveUserPagePreferences(prefs, $scope.dataSection);
|
|
}
|
|
}
|
|
|
|
// SA. ENV-799
|
|
$scope.loadCalendarData();
|
|
// ENV-539. For some reason select2 jQuery control loose selected value just after $scope.digest()
|
|
// so we need to set value again on next JS iteration.
|
|
$timeout(function () {
|
|
$('[name=selFilterElement]').select2("val", $scope.CalendarFilterMode.SelectedItemId);
|
|
}, 0, false);
|
|
}
|
|
|
|
$scope.loadCalendarData = function () {
|
|
// SA. ENV-799. Begin
|
|
$scope.calendarFilters.CompanyId = null;
|
|
$scope.calendarFilters.ViewId = null;
|
|
$scope.calendarFilters.TeamId = null;
|
|
$scope.calendarFilters.ResourceId = null;
|
|
|
|
if ($scope.CalendarFilterMode.IsCompany)
|
|
$scope.calendarFilters.CompanyId = $scope.CalendarFilterMode.SelectedItemId;
|
|
|
|
if ($scope.CalendarFilterMode.IsView)
|
|
$scope.calendarFilters.ViewId = $scope.CalendarFilterMode.SelectedItemId;
|
|
|
|
if ($scope.CalendarFilterMode.IsTeam)
|
|
$scope.calendarFilters.TeamId = $scope.CalendarFilterMode.SelectedItemId;
|
|
|
|
if ($scope.CalendarFilterMode.IsResource)
|
|
$scope.calendarFilters.ResourceId = $scope.CalendarFilterMode.SelectedItemId;
|
|
// SA. ENV-799. End
|
|
|
|
$scope.getCalendar();
|
|
}
|
|
|
|
// SA. ENV-799. Begin
|
|
$scope.switchCompanyFilterMode = function (preserverSelection) {
|
|
if (!$scope.CalendarFilterMode.IsCompany)
|
|
$scope.CalendarFilterMode.IsCompany = true;
|
|
|
|
$scope.CalendarFilterMode.IsView = false;
|
|
$scope.CalendarFilterMode.IsTeam = false;
|
|
$scope.CalendarFilterMode.IsResource = false;
|
|
$scope.CalendarFilterMode.FilteredEntityTitle = "Company";
|
|
|
|
if (($scope.availableFilterOptions != null) && ($scope.availableFilterOptions.Companies != null)) {
|
|
$scope.displayedOptions = $scope.availableFilterOptions.Companies;
|
|
for (var i = 0; i < $scope.displayedOptions.length; i++) {
|
|
var option = $scope.displayedOptions[i];
|
|
option.CSSClass = 'ddl-level-item';
|
|
if (option.Group && option.Group.Name && option.Group.Name.length > 0) {
|
|
option.CSSClass += ' pad-left';
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!preserverSelection) {
|
|
$scope.CalendarFilterMode.SelectedItemId = null;
|
|
$scope.$broadcast('selectedSourceChanged');
|
|
}
|
|
};
|
|
|
|
$scope.switchViewFilterMode = function (preserverSelection) {
|
|
if (!$scope.CalendarFilterMode.IsView)
|
|
$scope.CalendarFilterMode.IsView = true;
|
|
|
|
$scope.CalendarFilterMode.IsCompany = false;
|
|
$scope.CalendarFilterMode.IsTeam = false;
|
|
$scope.CalendarFilterMode.IsResource = false;
|
|
$scope.CalendarFilterMode.FilteredEntityTitle = "View";
|
|
|
|
if (($scope.availableFilterOptions != null) && ($scope.availableFilterOptions.Views != null))
|
|
$scope.displayedOptions = $scope.availableFilterOptions.Views;
|
|
|
|
if (!preserverSelection) {
|
|
$scope.CalendarFilterMode.SelectedItemId = null;
|
|
$scope.$broadcast('selectedSourceChanged');
|
|
}
|
|
};
|
|
|
|
$scope.switchTeamFilterMode = function (preserverSelection) {
|
|
if (!$scope.CalendarFilterMode.IsTeam)
|
|
$scope.CalendarFilterMode.IsTeam = true;
|
|
|
|
$scope.CalendarFilterMode.IsCompany = false;
|
|
$scope.CalendarFilterMode.IsView = false;
|
|
$scope.CalendarFilterMode.IsResource = false;
|
|
$scope.CalendarFilterMode.FilteredEntityTitle = "Team";
|
|
|
|
if (($scope.availableFilterOptions != null) && ($scope.availableFilterOptions.Teams != null))
|
|
$scope.displayedOptions = $scope.availableFilterOptions.Teams;
|
|
|
|
if (!preserverSelection) {
|
|
$scope.CalendarFilterMode.SelectedItemId = null;
|
|
$scope.$broadcast('selectedSourceChanged');
|
|
}
|
|
};
|
|
|
|
$scope.switchResourceFilterMode = function (preserverSelection) {
|
|
if (!$scope.CalendarFilterMode.IsResource)
|
|
$scope.CalendarFilterMode.IsResource = true;
|
|
|
|
$scope.CalendarFilterMode.IsCompany = false;
|
|
$scope.CalendarFilterMode.IsView = false;
|
|
$scope.CalendarFilterMode.IsTeam = false;
|
|
$scope.CalendarFilterMode.FilteredEntityTitle = "Resource";
|
|
|
|
$scope.IsCapacityModeActuals = true; // SA. ENV-886. Individual resource calendar shows actuals only
|
|
|
|
if (!preserverSelection) {
|
|
$scope.CalendarFilterMode.SelectedItemId = null;
|
|
$scope.$broadcast('selectedSourceChanged');
|
|
}
|
|
};
|
|
|
|
$scope.scrollHeader = function (evt) {
|
|
//if (flag) {
|
|
// return;
|
|
//}
|
|
var e = evt ? evt : window.event;
|
|
var t = e.target ? e.target : e.srcElement;
|
|
if (t.nodeType == 3) {
|
|
t = t.parentNode;
|
|
}
|
|
var tid = t.id.replace(':scroller', '');
|
|
var fh = ge$(tid + ':scroller:fx');
|
|
var sd = ge$(tid + ':scroller');
|
|
fh.style.left = (0 - sd.scrollLeft) + 'px';
|
|
var cf = ge$(tid + '_CFB');
|
|
if (cf) {
|
|
var dmt = parseInt(cf.getAttribute('dmt'));
|
|
cf.style.marginTop = (0 - (sd.scrollTop + dmt)) + 'px';
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
function ge$(d) { return document.getElementById(d); }
|
|
$scope.clearWidth = function () {
|
|
$scope.monthCol = [];
|
|
$scope.weekCol = [];
|
|
}
|
|
|
|
function checkBrowser() {
|
|
|
|
var userAgent = $window.navigator.userAgent;
|
|
|
|
var browsers = { chrome: /chrome/i, safari: /safari/i, firefox: /firefox/i, ie: /internet explorer/i, ie1: /trident/i };
|
|
|
|
for (var key in browsers) {
|
|
if (browsers[key].test(userAgent)) {
|
|
return key;
|
|
}
|
|
};
|
|
|
|
return 'unknown';
|
|
}
|
|
$scope.onResize = function () {
|
|
var headerWidth = $scope.headerWidth;
|
|
if ($scope.data) {
|
|
var tableHeightMin = 450;
|
|
var scrollBarsWH = $.getScrollBarWidthHeight();
|
|
var browserNonIE = checkBrowser() != "ie" && checkBrowser() != "ie1";//IE places scrollbars above the content and does not need additional space for scrollbar
|
|
|
|
var isAC = ($(".ac").length > 0);
|
|
//resize conteiner height
|
|
var noVScroll = ($(".ac-no-v-scroll").length > 0);
|
|
if (noVScroll || $(".height-container table").height() < tableHeightMin) {
|
|
$(".height-container").height($("#capacity-table").height() + scrollBarsWH[1]);
|
|
}
|
|
|
|
//resize conteiner width
|
|
var vertScrollShown = $("#capacity-table").height() > $(".height-container").height(); //$(".height-container table").height() > (tableHeightMin + +scrollBarWidth);
|
|
if (isAC) {
|
|
$(".width-container").width(Math.min((headerWidth * $scope.data.VisibleCellCount) + (browserNonIE && vertScrollShown ? scrollBarsWH[0] : 0) + 1,
|
|
$scope.containerWidth - $scope.firstColWidth));
|
|
} else {
|
|
$(".width-container").width(Math.min(headerWidth * $scope.data.VisibleCellCount + (browserNonIE && vertScrollShown ? scrollBarsWH[0] : 0),
|
|
$scope.containerWidth - $scope.firstColWidth - 1));
|
|
}
|
|
|
|
//resize conteiner height again when horizont scroll bar appears
|
|
if (noVScroll && browserNonIE) {
|
|
var horizontScrollShown = $("#capacity-table").width() > $(".height-container").width();
|
|
if (horizontScrollShown) {
|
|
$(".height-container").height($(".height-container").height() + scrollBarsWH[1]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}]).directive('watchResizing', function () {
|
|
return {
|
|
restrict: 'A',
|
|
link: function (scope, elem, attr, ctrl) {
|
|
elem.bind('resize', function (e) {
|
|
|
|
scope.containerWidth = $("#controller1").outerWidth();
|
|
scope.firstColWidth = $("div[id*='fxcol'").width();
|
|
|
|
scope.onResize();
|
|
|
|
});
|
|
}
|
|
};
|
|
})
|
|
.directive('scrollHeader', function () {
|
|
return {
|
|
restrict: 'A',
|
|
link: function (scope, elem, attr, ctrl) {
|
|
elem.bind('scroll', function (e) {
|
|
scope.scrollHeader(e);
|
|
});
|
|
}
|
|
};
|
|
});
|