EnVisageOnline/Main-RMO/Source/EnVisage/Scripts/Angular/Controllers/teamInfoController.js

545 lines
21 KiB
JavaScript

'use strict';
app.controller('teamInfoController', ['$scope', '$http', 'hoursResourcesConverter', 'cellHighligting', 'teamInfoService', function ($scope, $http, hoursResourcesConverter, cellHighligting, teamInfoService) {
var collapsedIcon = 'fa-plus-square',
nonCollapsedIcon = 'fa-minus-square';
var RowType = {
Vacations: 1,
Trainings: 2,
Team: 3,
ExpenditureCategory: 4
};
$scope.InternalData = null; //DAL data model
$scope.DisplayMode = { // Page Options
IsUOMHours: true, // display data in Hours
GroupCapacityByTeam: false, // do not group capacity by team
TotalsAs: 1, // Allocated/Capacity
CapacityView: false, // Planned
IsAvgMode: false // Totals average mode. SA. ENV-1046
};
$scope.DisplayData = {}; // UI data model
$scope.DisplayDataOrder = ["Vacations", "Trainings"];
$scope.$on('rebindTeamInfo', function (event, data) {
if (!data)
return;
$scope.InternalData = {
Vacations: data.Vacations || {},
Trainings: data.Trainings || {},
Header: data.Header || {}
};
initOptions(data.DisplayMode);
initRows();
});
$scope.$on('groupCapacityByTeamChanged', function (event, data) {
$scope.DisplayMode.GroupCapacityByTeam = data;
initRows();
});
$scope.$on('changeUOMMode', function (event, data) {
$scope.DisplayMode.IsUOMHours = data;
initRows();
});
$scope.$on('totalsAsChanged', function (event, data) {
$scope.DisplayMode.TotalsAs = data;
initRows();
});
$scope.$on('capacityViewChanged', function (event, data) {
$scope.DisplayMode.CapacityView = data;
initRows();
});
$scope.$on('expenditureCategoryValueChanged', function (event, data) {
if (!data)
return;
expenditureCategoryValueChanged(data.TeamId, data.ExpenditureCategoryId, data.WeekIndex);
});
$scope.$on('resourceValueChanged', function (event, data) {
if (!data)
return;
resourceValueChanged(data.TeamId, data.ExpenditureCategoryId, data.ResourceId, data.WeekIndex);
});
$scope.toggleExpCategoryRow = function (key, $event) {
if (!!$event && angular.isFunction($event.preventDefault))
$event.preventDefault();
$scope.DisplayData[key].IsCollapsed = !$scope.DisplayData[key].IsCollapsed;
};
$scope.isAvgMode = function () {
return $scope.DisplayMode.IsAvgMode && !$scope.DisplayMode.IsUOMHours;
}
// set page options with values received from outer scope
function initOptions(options) {
if (!options)
return;
var modes = Object.keys(options);
if (modes.indexOf('IsUOMHours') >= 0)
$scope.DisplayMode.IsUOMHours = options.IsUOMHours;
if (modes.indexOf('GroupCapacityByTeam') >= 0)
$scope.DisplayMode.GroupCapacityByTeam = options.GroupCapacityByTeam;
if (modes.indexOf('TotalsAs') >= 0)
$scope.DisplayMode.TotalsAs = options.TotalsAs;
if (modes.indexOf('CapacityView') >= 0)
$scope.DisplayMode.CapacityView = options.CapacityView;
if (modes.indexOf('IsAvgMode') >= 0)
$scope.DisplayMode.IsAvgMode = options.IsAvgMode;
}
//==========Start Convert data model to UI data model methods=============//
function initVacationsRow() {
return {
Name: "Vacations",
Type: RowType.Vacations,
Cells: new Array($scope.InternalData.Header.Weeks.length)
};
}
function initTrainingsRow() {
return {
Name: "Trainings",
Type: RowType.Trainings,
Cells: new Array($scope.InternalData.Header.Weeks.length)
};
}
function initTeamRow(id, name) {
return {
Id: id,
Name: name,
Type: RowType.Team,
Cells: new Array($scope.InternalData.Header.Weeks.length),
CSSClass: new Array($scope.InternalData.Header.Weeks.length)
};
}
function initExpCategoryRow(category, teamId) {
return {
Id: category.Id,
TeamId: teamId,
Name: category.Name,
Type: RowType.ExpenditureCategory,
IsCollapsed: true,
Cells: new Array($scope.InternalData.Header.Weeks.length),
Resources: [],
CSSClass: new Array($scope.InternalData.Header.Weeks.length)
};
}
function initResourceRow(resource, catId, teamId) {
return {
Id: resource.Id,
ExpCatId: catId,
TeamId: teamId,
Name: resource.Name,
Cells: new Array($scope.InternalData.Header.Weeks.length),
CSSClass: new Array($scope.InternalData.Header.Weeks.length)
};
}
function initRows() {
if (!$scope.InternalData)
return;
$scope.DisplayData = {
"Vacations": initVacationsRow(),
"Trainings": initTrainingsRow()
};
$scope.DisplayDataOrder = ["Vacations", "Trainings"];
var teams = teamInfoService.getAll();
if (!!teams) {
for (var teamId in teams) {
var team = teams[teamId];
if ($scope.DisplayMode.GroupCapacityByTeam === true) {
$scope.DisplayData[team.Id] = initTeamRow(team.Id, team.Name);
$scope.DisplayDataOrder.push(team.Id);
}
if (!team.ExpCategories)
continue;
for (var expCatId in team.ExpCategories) {
var ec = team.ExpCategories[expCatId];
var ecKey = $scope.DisplayMode.GroupCapacityByTeam === true ? team.Id + '-' + ec.Id : ec.Id;
var teamId = $scope.DisplayMode.GroupCapacityByTeam === true ? team.Id : null;
if (!$scope.DisplayData[ecKey]) {
$scope.DisplayData[ecKey] = initExpCategoryRow(ec, teamId);
$scope.DisplayDataOrder.push(ecKey);
}
if (!ec.Resources)
continue;
for (var resourceId in ec.Resources) {
var resource = initResourceRow(ec.Resources[resourceId], ec.Id, teamId);
$scope.DisplayData[ecKey].Resources.push(resource);
}
}
}
}
initRowsData();
}
function initRowsData() {
if (!$scope.InternalData.Header.Months || !$scope.InternalData.Header.Weeks)
return;
for (var i in $scope.DisplayData) {
var fillCellFunction = undefined,
originalRow = $scope.DisplayData[i],
expCat = undefined,
team = undefined,
resource = undefined;
switch (originalRow.Type) {
case RowType.Vacations:
fillCellFunction = fillVacationCell;
break;
case RowType.Trainings:
fillCellFunction = fillTrainingCell;
break;
case RowType.Team:
fillCellFunction = fillTeamCell;
team = teamInfoService.getById(originalRow.Id);
break;
case RowType.ExpenditureCategory:
fillCellFunction = fillECTotalCell;
team = teamInfoService.getById(originalRow.TeamId);
if (team != null)
expCat = teamInfoService.getExpenditureCategoryInTeam(originalRow.TeamId, originalRow.Id);
break;
}
for (var mIndex in $scope.InternalData.Header.Months) {
var month = $scope.InternalData.Header.Months[mIndex];
if (!month.Childs)
continue;
for (var wIndex in month.Childs) {
if (fillCellFunction == undefined || typeof fillCellFunction !== 'function') {
updateTotalCell(originalRow, month.Childs[wIndex], month.SelfIndexInWeeks, [0, 0]);
} else {
fillCellFunction(month.Childs[wIndex], month.SelfIndexInWeeks, originalRow, team, expCat);
}
}
}
}
}
function fillVacationCell(wIndex, mIndex, originalRow) {
var week = $scope.InternalData.Header.Weeks[wIndex];
var value = 0;
for (var expCatId in $scope.InternalData.Vacations) {
var v = $scope.InternalData.Vacations[expCatId][week.Milliseconds] || 0;
if (!$scope.DisplayMode.IsUOMHours) {
value += hoursResourcesConverter.convertToResources(expCatId, v);
}
else {
value += v;
}
}
updateSimpleCell(originalRow, wIndex, mIndex, value);
}
function fillTrainingCell(wIndex, mIndex, originalRow) {
var week = $scope.InternalData.Header.Weeks[wIndex];
var value = 0;
for (var expCatId in $scope.InternalData.Trainings) {
var v = $scope.InternalData.Trainings[expCatId][week.Milliseconds] || 0;
if (!$scope.DisplayMode.IsUOMHours) {
value += hoursResourcesConverter.convertToResources(expCatId, v);
}
else {
value += v;
}
}
updateSimpleCell(originalRow, wIndex, mIndex, value);
}
function fillECTotalCell(wIndex, mIndex, originalRow, team, expCat) {
var week = $scope.InternalData.Header.Weeks[wIndex];
var values = {
Value1: 0,
Value2: 0
};
var resources = [];
if (!team) {
var teams = teamInfoService.getAll();
if (!!teams) {
for (var teamId in teams) {
var teamItem = teams[teamId];
for (var catKey in teamItem.ExpCategories) {
if (teamItem.ExpCategories[catKey].Id == originalRow.Id) {
values = getEcCellValue(teamItem.ExpCategories[catKey], week.Milliseconds, values);
for (var resourceId in teamItem.ExpCategories[catKey].Resources) {
resources.push(teamItem.ExpCategories[catKey].Resources[resourceId]);
}
}
}
}
}
} else {
if (!expCat) {
throw 'expCat for the team ' + team.Name + ' (' + team.Id + ') is not set';
} else {
values = getEcCellValue(expCat, week.Milliseconds);
for (var resourceId in expCat.Resources) {
resources.push(expCat.Resources[resourceId]);
}
}
}
if (!$scope.DisplayMode.IsUOMHours) {
values.Value1 = hoursResourcesConverter.convertToResources(originalRow.Id, values.Value1);
values.Value2 = hoursResourcesConverter.convertToResources(originalRow.Id, values.Value2);
}
updateTotalCell(originalRow, wIndex, mIndex, values);
updateResourcesCell(originalRow, wIndex, mIndex, resources, week.Milliseconds);
}
function fillTeamCell(wIndex, mIndex, originalRow, team) {
if (team == null)
return;
var week = $scope.InternalData.Header.Weeks[wIndex];
var values = {
Value1: 0,
Value2: 0
};
for (var catKey in team.ExpCategories) {
values = getEcCellValue(team.ExpCategories[catKey], week.Milliseconds, values);
}
if (!$scope.DisplayMode.IsUOMHours) {
values.Value1 = hoursResourcesConverter.convertToResources(catKey, values.Value1);
values.Value2 = hoursResourcesConverter.convertToResources(catKey, values.Value2);
}
updateTotalCell(originalRow, wIndex, mIndex, values);
}
function updateSimpleCell(originalRow, weekIndex, monthIndex, newValue) {
if (!originalRow || !originalRow.Cells)
return;
if (originalRow.Cells[monthIndex] == undefined)
originalRow.Cells[monthIndex] = 0;
if (originalRow.Cells[weekIndex] == undefined)
originalRow.Cells[weekIndex] = 0;
// we should increase/decrease month total value by delta between new and old values
var totalsDelta = newValue;
var showAverageTotals = $scope.isAvgMode();
if (showAverageTotals) {
var monthIndexInMonthes = $scope.InternalData.Header.Weeks[weekIndex].ParentIndex;
var weekCountInThisMonth = $scope.InternalData.Header.Months[monthIndexInMonthes].Childs.length;
totalsDelta = totalsDelta / weekCountInThisMonth;
}
originalRow.Cells[monthIndex] += totalsDelta - originalRow.Cells[weekIndex];
originalRow.Cells[weekIndex] = newValue;
}
function updateResourceCell(expCatRow, originalRow, weekIndex, monthIndex, newValues) {
if (!originalRow || !originalRow.Cells)
return;
if (originalRow.Cells[monthIndex] == undefined)
originalRow.Cells[monthIndex] = { Value1: 0, Value2: 0 };
if (originalRow.Cells[weekIndex] == undefined)
originalRow.Cells[weekIndex] = { Value1: 0, Value2: 0 };
// we should to increase/decrease month total value by delta between new and old values
var totalsDelta = {}; // SA. ENV-1046
totalsDelta.Value1 = newValues.Value1 - originalRow.Cells[weekIndex].Value1;
totalsDelta.Value2 = newValues.Value2 - originalRow.Cells[weekIndex].Value2;
var showAverageTotals = $scope.isAvgMode();
if (showAverageTotals) {
var monthIndexInMonthes = $scope.InternalData.Header.Weeks[weekIndex].ParentIndex;
var weekCountInThisMonth = $scope.InternalData.Header.Months[monthIndexInMonthes].Childs.length;
totalsDelta.Value1 = totalsDelta.Value1 / weekCountInThisMonth;
totalsDelta.Value2 = totalsDelta.Value2 / weekCountInThisMonth;
}
originalRow.Cells[monthIndex].Value1 += totalsDelta.Value1;
originalRow.Cells[monthIndex].Value2 += totalsDelta.Value2;
originalRow.Cells[weekIndex] = newValues;
cellHighligting.setCellCssClasses(expCatRow, originalRow, weekIndex);
cellHighligting.setCellCssClasses(expCatRow, originalRow, monthIndex);
}
function updateResourcesCell(originalRow, weekIndex, monthIndex, resources, milliseconds) {
if (!originalRow || !originalRow.Resources)
return;
for (var resIndex = 0; resIndex < originalRow.Resources.length; resIndex++) {
var resRow = originalRow.Resources[resIndex];
for (var i = 0; i < resources.length; i++) {
if (resRow.Id == resources[i].Id) {
var values = getResourceCellValue(resources[i], milliseconds);
if (!$scope.DisplayMode.IsUOMHours) {
values.Value1 = hoursResourcesConverter.convertToResources(originalRow.Id, values.Value1);
values.Value2 = hoursResourcesConverter.convertToResources(originalRow.Id, values.Value2);
}
updateResourceCell(originalRow, resRow, weekIndex, monthIndex, values);
continue;
}
}
}
}
function updateTotalCell(originalRow, weekIndex, monthIndex, newValues) {
if (!originalRow || !originalRow.Cells)
return;
if (originalRow.Cells[monthIndex] == undefined)
originalRow.Cells[monthIndex] = { Value1: 0, Value2: 0 };
if (originalRow.Cells[weekIndex] == undefined)
originalRow.Cells[weekIndex] = { Value1: 0, Value2: 0 };
// we should increase/decrease month total value by delta between new and old values
var totalsDelta = {}; // SA. ENV-1046
totalsDelta.Value1 = newValues.Value1 - originalRow.Cells[weekIndex].Value1;
totalsDelta.Value2 = newValues.Value2 - originalRow.Cells[weekIndex].Value2;
var showAverageTotals = $scope.isAvgMode();
if (showAverageTotals) {
var monthIndexInMonthes = $scope.InternalData.Header.Weeks[weekIndex].ParentIndex;
var weekCountInThisMonth = $scope.InternalData.Header.Months[monthIndexInMonthes].Childs.length;
totalsDelta.Value1 = totalsDelta.Value1 / weekCountInThisMonth;
totalsDelta.Value2 = totalsDelta.Value2 / weekCountInThisMonth;
}
originalRow.Cells[monthIndex].Value1 += totalsDelta.Value1;
originalRow.Cells[monthIndex].Value2 += totalsDelta.Value2;
originalRow.Cells[weekIndex] = newValues;
cellHighligting.setCellCssClasses(originalRow, null, weekIndex);
cellHighligting.setCellCssClasses(originalRow, null, monthIndex);
}
// returns an object with values to display in Expenditure Category row (bottom part)
function getEcCellValue(expCat, index, values) {
if (!values) {
values = {
Value1: 0,
Value2: 0
};
}
if ($scope.DisplayMode.CapacityView) { // capacity = Actual
switch (parseInt($scope.DisplayMode.TotalsAs)) {
case 1:
//Allocated/Capacity
values.Value1 += expCat.AllocatedCapacity[index] || 0;
values.Value2 += expCat.ActualCapacityValues[index] || 0;
break;
case 2:
//Need/Capacity
values.Value1 += expCat.NeedCapacity[index] || 0;
values.Value2 += expCat.ActualCapacityValues[index] || 0;
break;
case 3:
//Allocated/Need
values.Value1 += expCat.AllocatedCapacity[index] || 0;
values.Value2 += expCat.NeedCapacity[index] || 0;
break;
}
} else { // capacity = Planned
switch (parseInt($scope.DisplayMode.TotalsAs)) {
case 1:
//Allocated/Capacity
values.Value1 += expCat.AllocatedCapacity[index] || 0;
values.Value2 += expCat.PlannedCapacityValues[index] || 0;
break;
case 2:
//Need/Capacity
values.Value1 += expCat.NeedCapacity[index] || 0;
values.Value2 += expCat.PlannedCapacityValues[index] || 0;
break;
case 3:
//Allocated/Need
values.Value1 += expCat.AllocatedCapacity[index] || 0;
values.Value2 += expCat.NeedCapacity[index] || 0;
break;
}
}
return values;
}
// returns an object with values to display in Resource row (bottom part)
function getResourceCellValue(resource, index) {
return {
Value1: resource.AllocatedCapacity[index] || 0,
Value2: resource.TotalCapacity[index] || 0
};
}
//==========End Convert data model to UI data model methods=============//
function expenditureCategoryValueChanged(teamId, expenditureCategoryId, weekIndex) {
if (!teamId || !expenditureCategoryId)
return;
var team = teamInfoService.getById(teamId);
if (!team)
return;
var expCategoryInTeam = teamInfoService.getExpenditureCategoryInTeam(teamId, expenditureCategoryId);
if (!expCategoryInTeam)
return;
var week = $scope.InternalData.Header.Weeks[weekIndex];
if (!week)
return;
var month = $scope.InternalData.Header.Months[week.ParentIndex];
if (!month)
return;
var ecKey = $scope.DisplayMode.GroupCapacityByTeam === true ? team.Id + '-' + expenditureCategoryId : expenditureCategoryId;
var originalRow = $scope.DisplayData[ecKey];
if (!originalRow)
return;
if ($scope.DisplayMode.GroupCapacityByTeam === true) {
fillECTotalCell(weekIndex, month.SelfIndexInWeeks, originalRow, team, expCategoryInTeam);
if (!!$scope.DisplayData[team.Id]) {
fillTeamCell(weekIndex, month.SelfIndexInWeeks, $scope.DisplayData[team.Id], team);
}
} else {
fillECTotalCell(weekIndex, month.SelfIndexInWeeks, originalRow);
}
}
function resourceValueChanged(teamId, expenditureCategoryId, resourceId, weekIndex) {
if (!teamId || !expenditureCategoryId || !resourceId)
return;
var team = teamInfoService.getById(teamId);
if (!team)
return;
var expCategoryInTeam = team.ExpCategories[expenditureCategoryId];
if (!expCategoryInTeam)
return;
var week = $scope.InternalData.Header.Weeks[weekIndex];
if (!week)
return;
var month = $scope.InternalData.Header.Months[week.ParentIndex];
if (!month)
return;
var ecKey = $scope.DisplayMode.GroupCapacityByTeam === true ? team.Id + '-' + expenditureCategoryId : expenditureCategoryId;
var originalRow = $scope.DisplayData[ecKey];
if (!originalRow)
return;
if ($scope.DisplayMode.GroupCapacityByTeam === true) {
fillECTotalCell(weekIndex, month.SelfIndexInWeeks, originalRow, team, expCategoryInTeam);
if (!!$scope.DisplayData[team.Id]) {
fillTeamCell(weekIndex, month.SelfIndexInWeeks, $scope.DisplayData[team.Id], team);
}
} else {
fillECTotalCell(weekIndex, month.SelfIndexInWeeks, originalRow);
}
}
}]);