EnVisageOnline/Main/Source/EnVisage/Scripts/Angular/Controllers/ActivityCalendarControllers/resourceCalendarController.js

768 lines
42 KiB
JavaScript

'use strict';
app
.controller('resourceCalendarController', ['$scope', '$q', 'activityCalendarService', 'teamInfoService', 'activityCalendarUIService', 'dataSources', 'hoursResourcesConverter', 'roundService', '$filter', function ($scope, $q, activityCalendarService, teamInfoService, activityCalendarUIService, dataSources, hoursResourcesConverter, roundService, $filter) {
var commonErrorMessage = 'An error occurred while processing your request. Please, try again later.';
var calendarDataUrl = '/CapacityManagement/GetActivityCalendar';
var projectsByResourceCache = {}; // cache for aggregated ECs by project for "group by teams" mode
var resourceCache = {}; // cache for the resource info, this calendar is displayed for
var nonProjectTimeCache = {}; // cache for non-project time data.
var nonProjectTimeCategoryCache = {}; // cache for non-project time data.
$scope.ViewModel = {
DisplayMode: null,
Header: null,
Rows: null,
CurrentlyAssignedRow: null,
TotalRow: null,
RemainingCapacityRow: null,
NonProjectTimeTotalRow: null,
DataLoaded: false,
Visibility: {
ShowForecast: false,
ShowActuals: false,
ForecastEditable: false,
ActualsEditable: false
},
};
$scope.Filter = null;
/* Event listeners */
$scope.$on('ac.rebuild-calendar', rebuildCalendarHandler);
$scope.$on('ac.options-changed', optionsChangedHandler);
/* Methods for interaction with view */
$scope.init = function (filter, displayMode) {
rebuildCalendarHandler(null, filter, displayMode);
};
$scope.toggleMonth = function (monthIndex) {
$scope.ViewModel.Header.toggleMonth(monthIndex);
};
$scope.toggleRow = function (uiRow, $event) {
if ($($event.target).parents('.menuGroup').length > 0)
return;
// to-do: we should keep collapsed state in data-model items between possible future postbacks
var dataModel = activityCalendarService.dataItemStub || {};
activityCalendarUIService.toggleRow(uiRow, dataModel);
};
$scope.ToggleStatus = function ($event, projectId, scenario) {
var btn = $($event.target).closest('.popover-warning');
if (btn.length == 1) {
activityCalendarUIService.toggleStatus(btn, projectId, scenario)
.then(function (result) {
if (!!result)
rebuildCalendarHandler($event, $scope.Filter, $scope.ViewModel.DisplayMode, true);
})
.then(null, function () {
showErrorModal(null, 'An error occurred while toggling scenario status', '000009');
});
}
};
$scope.AddScenario = function ($event, projectId) {
activityCalendarUIService.openCreateScenarioWz(projectId);
};
$scope.checkResourceValue = function (row, $index, $data) {
if (!row || !row.ExpenditureCategoryId || !row.ExpenditureCategoryId.length || row.IsMultipleECs || !$scope.Filter.EntityId) {
return;
}
var resourceId = $scope.Filter.EntityId;
var filter = $scope.Filter,
header = $scope.ViewModel.Header,
isUOMHours = $scope.ViewModel.DisplayMode.IsUOMHours,
isAvgMode = $scope.ViewModel.DisplayMode.IsAvgMode();
var result = activityCalendarUIService.checkResourceValue(filter, header, row.Id, { Id: row.ExpenditureCategoryId[0] }, resourceId, row, isUOMHours, isAvgMode, $index, $data, false);
if (typeof result === 'object' && angular.isArray(result) && result.length > 0) {
updateProjectRows(result, row.Id);
updateTotalRows(result);
refreshResourceStyles(result);
dataChanged();
return false;
}
return result;
};
$scope.checkResourceGrandTotalValue = function (row, $data) {
if (!row || !row.ExpenditureCategoryId || !row.ExpenditureCategoryId.length || row.IsMultipleECs || !row.ActiveScenario) {
return;
}
var resourceId = $scope.Filter.EntityId;
var filter = $scope.Filter,
header = $scope.ViewModel.Header,
isUOMHours = $scope.ViewModel.DisplayMode.IsUOMHours,
isAvgMode = $scope.ViewModel.DisplayMode.IsAvgMode();
var result = activityCalendarUIService.checkResourceGrandTotalValue(filter, header, row.Id, row.ActiveScenario.StartDate, row.ActiveScenario.EndDate, { Id: row.ExpenditureCategoryId[0] }, resourceId, row, isUOMHours, isAvgMode, $data, false);
if (typeof result === 'object' && angular.isArray(result) && result.length > 0) {
updateProjectRows(result, row.Id);
updateTotalRows(result);
refreshResourceStyles(result);
dataChanged();
return false;
}
return result;
};
$scope.checkResourceActualsValue = function (row, $index, $data) {
if (!row || !row.ExpenditureCategory || !row.ExpenditureCategory.Id || !$scope.Filter.EntityId) {
return;
}
var resourceId = $scope.Filter.EntityId;
var filter = $scope.Filter,
header = $scope.ViewModel.Header,
isUOMHours = $scope.ViewModel.DisplayMode.IsUOMHours,
isAvgMode = $scope.ViewModel.DisplayMode.IsAvgMode();
var result = activityCalendarUIService.checkResourceValue(filter, header, row.Id, { Id: row.ExpenditureCategory.Id }, resourceId, row, isUOMHours, isAvgMode, $index, $data, true);
if (typeof result === 'object' && angular.isArray(result) && result.length > 0) {
updateActualTotalRow(result);
dataChanged();
return false;
}
return result;
};
$scope.checkResourceActualsGrandTotalValue = function (row, $data) {
if (!row || !row.ExpenditureCategory || !row.ExpenditureCategory.Id || !row.ActiveScenario || !$scope.Filter.EntityId) {
return;
}
var resourceId = $scope.Filter.EntityId;
var filter = $scope.Filter,
header = $scope.ViewModel.Header,
isUOMHours = $scope.ViewModel.DisplayMode.IsUOMHours,
isAvgMode = $scope.ViewModel.DisplayMode.IsAvgMode();
var result = activityCalendarUIService.checkResourceGrandTotalValue(filter, header, row.Id, row.ActiveScenario.StartDate, row.ActiveScenario.EndDate, { Id: row.ExpenditureCategory.Id }, resourceId, row, isUOMHours, isAvgMode, $data, true);
if (typeof result === 'object' && angular.isArray(result) && result.length > 0) {
updateActualTotalRow(result);
dataChanged();
return false;
}
return result;
};
$scope.checkNptResourceValue = function (nptCatRow, nptItemRow, $index, $data) {
if (!nptCatRow || !nptItemRow || nptItemRow.IsTeamWide || !nptItemRow.Children || !nptItemRow.Children.length)
return;
var nptResourceRow = nptItemRow.Children[0];
var filter = $scope.Filter,
header = $scope.ViewModel.Header,
isUOMHours = $scope.ViewModel.DisplayMode.IsUOMHours,
isAvgMode = $scope.ViewModel.DisplayMode.IsAvgMode(),
nptTotalRow = $scope.ViewModel.NonProjectTimeTotalRow;
var rollupRows = [];
rollupRows.push(nptTotalRow);
rollupRows.push(nptCatRow);
rollupRows.push(nptItemRow);
rollupRows.push($scope.ViewModel.TotalRow);
var result = activityCalendarUIService.checkNptResourceValue(filter, header, $scope.ViewModel.RemainingCapacityRow,
rollupRows, nptCatRow, nptItemRow, nptResourceRow, isUOMHours, isAvgMode, $index, $data);
// if result is not false it is incorrect one and we do not need to recalculate availability in this case
if (typeof result === 'object' && angular.isArray(result) && result.length > 0) {
dataChanged();
return false;
}
return result;
};
$scope.watchKeyInput = function (t) {
activityCalendarUIService.watchKeyInput(t);
};
$scope.onTxtBlur = function (t) {
activityCalendarUIService.onTxtBlur(t);
};
/* Event handlers */
function rebuildCalendarHandler(event, filter, displayMode, forceDataReload, successCallback) {
// if filter is changed we need to invalidate cache
if ($scope.Filter && !activityCalendarService.cacheKeysEqual($scope.Filter, filter)) {
activityCalendarService.invalidateCache($scope.Filter);
}
$scope.ViewModel.DataLoaded = false;
$scope.ViewModel.DisplayMode = angular.copy(displayMode || {});
$scope.Filter = angular.copy(filter || {});
blockUI();
hoursResourcesConverter.load(forceDataReload).then(function () {
var loadCalendarTask = activityCalendarService.getActivityCalendar(calendarDataUrl, filter, forceDataReload);
var nptCategoriesTask = dataSources.getNonProjectTimeCategories();
var rdRightsTask = activityCalendarService.getResourceDetailsRights();
var resourceLoadTask = dataSources.loadResourcesByResourceIds([filter.EntityId]);
var cachedTemplates = activityCalendarUIService.cacheTemplates();
var dateRangeTask = dataSources.loadAvailableDateRange();
var allTasks = [loadCalendarTask, nptCategoriesTask, rdRightsTask, resourceLoadTask, dateRangeTask].concat(cachedTemplates);
$q.all(allTasks)
.then(function (asyncResults) {
var calendar = asyncResults[0]; // get calendar from loadCalendarTask
var rdRights = asyncResults[2]; // get resource details rights from rdRightsTask
nonProjectTimeCategoryCache = asyncResults[1]; // get npt categories from nptCategoriesTask
createViewModel4Visibility(rdRights);
createViewModel(calendar);
fillViewModelWithData(calendar);
toggleParts();
toggleHoursResourcesMode();
toggleSortBy();
toggleSecurityMode();
toggleBarsValuesMode();
toggleMonths();
unblockUI();
if (typeof successCallback === 'function') {
successCallback();
}
if (angular.isObject(calendar))
$scope.ViewModel.DataLoaded = true;
})
.then(null, function () {
unblockUI();
showErrorModal('Oops!', commonErrorMessage);
});
}).then(null, function () {
unblockUI();
showErrorModal('Oops!', commonErrorMessage);
});
};
function optionsChangedHandler(event, displayMode, key, newValue) {
$scope.ViewModel.DisplayMode = displayMode || {};
switch (key) {
case 'uomMode':
toggleHoursResourcesMode();
$scope.$broadcast('changeUOMMode', newValue);
break;
case 'capBarMode':
toggleBarsValuesMode();
break;
case 'defaultView':
toggleMonths();
break;
case 'sortBy':
case 'sortOrder':
toggleSortBy();
break;
case 'showParts':
toggleParts();
toggleSortBy();
toggleHoursResourcesMode();
break;
case 'capacityView':
toggleCapacityType();
$scope.$broadcast('capacityViewChanged', newValue);
break;
default:
break;
};
};
function dataChanged() {
$scope.$emit('ac.calendarDataChanged');
};
/* Methods for creating view models */
function createViewModel4Visibility(rdRights) {
if (!rdRights || !Object.keys(rdRights).length) {
return;
}
$scope.ViewModel.Visibility.ShowForecast = (rdRights.Read === true || rdRights.Write === true) &&
(rdRights.ForecastRead === true || rdRights.ForecastWrite === true);
$scope.ViewModel.Visibility.ShowActuals = (rdRights.Read === true || rdRights.Write === true) &&
(rdRights.ActualsRead === true || rdRights.ActualsWrite === true);
$scope.ViewModel.Visibility.ForecastEditable = (rdRights.Write === true && rdRights.ForecastWrite === true);
$scope.ViewModel.Visibility.ActualsEditable = (rdRights.Write === true && rdRights.ActualsWrite === true);
};
function createViewModel(model) {
var startDate = new Date().getTime();
createHeaderViewModel(model.WeekEndings);
createRowsViewModel(model);
var endDate = new Date().getTime();
console.log('creating view model: ' + (endDate - startDate) + ' ms');
};
function createHeaderViewModel(weekEndings) {
$scope.ViewModel.Header = (new GridHeader(weekEndings || {}).create());
};
function createRowsViewModel(model) {
if (!model || !model.Projects)
return;
$scope.ViewModel.Rows = [];
projectsByResourceCache = activityCalendarService.getResourcesWithAssignedProjects($scope.Filter);
if (projectsByResourceCache && projectsByResourceCache[$scope.Filter.EntityId]) {
var currentResource = projectsByResourceCache[$scope.Filter.EntityId];
if (currentResource && currentResource.Projects && (Object.keys(currentResource.Projects).length > 0)) {
var sortedProjects = $filter('sortObjectsBy')(currentResource.Projects, 'Name', false);
for (var index = 0; index < sortedProjects.length; index++) {
var project = sortedProjects[index];
var projectModel = activityCalendarUIService.createViewModel4Project(project, null, $scope.Filter);
var projectEditableModel = angular.extend({}, projectModel, activityCalendarUIService.createViewModelEditableBasic());
if (projectEditableModel) {
var actualsViewModel = angular.copy(projectEditableModel);
projectEditableModel.IsMultipleECs = project.IsMultipleECs;
projectEditableModel.ExpenditureCategoryId = project.ExpenditureCategoryId;
projectEditableModel.Teams = [];
projectEditableModel.Children = [];
// Set custom row teamplates
projectEditableModel.Templates.Main = activityCalendarUIService.viewRowTemplates.projectRcRowTemplate;
projectEditableModel.Templates.Numbers = activityCalendarUIService.viewRowTemplates.projectRcRowNumbersTemplate;
$scope.ViewModel.Rows.push(projectEditableModel);
if ($scope.ViewModel.Visibility.ShowActuals) {
if (!$scope.ViewModel.Visibility.ShowForecast) {
var projectFullName = actualsViewModel.Name;
if ((actualsViewModel.ParentProjectId != actualsViewModel.Id) && (actualsViewModel.ParentName)) {
// Name for part in project with parts
projectFullName = actualsViewModel.PartName + ": " + actualsViewModel.ParentName;
}
actualsViewModel.Name = 'Actual ' + projectFullName;
actualsViewModel.Initialized = true;
actualsViewModel.Show = true;
}
else {
actualsViewModel.Name = 'Actual';
}
actualsViewModel.RowType = 'ProjectResourceActuals',
actualsViewModel.IsMultipleECs = false;
actualsViewModel.Teams = [];
actualsViewModel.ExpenditureCategory = {
Id: currentResource.OwnExpenditureCategoryId
};
// Set custom row teamplates
actualsViewModel.Templates.Main = activityCalendarUIService.viewRowTemplates.projectActualsRowTemplate;
actualsViewModel.Templates.Numbers = activityCalendarUIService.viewRowTemplates.projectActualsRowNumbersTemplate;
projectEditableModel.Children.push(actualsViewModel);
}
}
}
}
}
// Create non-project time rows
nonProjectTimeCache = activityCalendarUIService.getNonProjectTimeDataModel(nonProjectTimeCategoryCache, $scope.DisplayMode.GroupBy.Value);
createNonProjectTimeRowModels();
// Create total rows
createTotalRowModels();
};
function createNonProjectTimeRowModels() {
$scope.ViewModel.NonProjectTimeTotalRow = activityCalendarUIService.createViewModel4NptTotalRow('Non-Project Time', nonProjectTimeCache[$scope.Filter.EntityId]);
};
function createTotalRowModels() {
$scope.ViewModel.RemainingCapacityRow = activityCalendarUIService.createViewModel4TotalRow('Remaining Capacity');
$scope.ViewModel.CurrentlyAssignedRow = activityCalendarUIService.createViewModel4TotalRow('Currently Assigned');
$scope.ViewModel.TotalRow = activityCalendarUIService.createViewModel4TotalRow('Total');
$scope.ViewModel.TotalRow.Collapsed = true;
if ($scope.ViewModel.Visibility.ShowActuals && $scope.ViewModel.Rows && ($scope.ViewModel.Rows.length > 0)) {
var actualsTotalRow = activityCalendarUIService.createViewModel4TotalRow('Actual');
if (!$scope.ViewModel.Visibility.ShowForecast) {
actualsTotalRow.Name += ' Total';
actualsTotalRow.Initialized = true;
actualsTotalRow.Show = true;
}
$scope.ViewModel.TotalRow.Children = [actualsTotalRow];
}
};
function getTotalRows() {
var rows = [];
if ($scope.ViewModel.NonProjectTimeTotalRow) {
rows.push($scope.ViewModel.NonProjectTimeTotalRow);
}
if ($scope.ViewModel.CurrentlyAssignedRow) {
rows.push($scope.ViewModel.CurrentlyAssignedRow);
}
if ($scope.ViewModel.TotalRow) {
rows.push($scope.ViewModel.TotalRow);
if ($scope.ViewModel.TotalRow.Children && $scope.ViewModel.TotalRow.Children.length) {
// Actual child row for Total row
rows.push($scope.ViewModel.TotalRow.Children[0]);
}
}
if ($scope.ViewModel.RemainingCapacityRow) {
rows.push($scope.ViewModel.RemainingCapacityRow);
}
return rows;
};
/* Root methods for creating view models and filling them with data */
function fillViewModelWithData(model) {
var startDate = new Date().getTime();
if ($scope.ViewModel.Rows && projectsByResourceCache && (Object.keys(projectsByResourceCache).length > 0)) {
var resourceData = projectsByResourceCache[$scope.Filter.EntityId];
if (!resourceData)
return;
for (var i = 0; i < $scope.ViewModel.Rows.length; i++) {
var projectRow = $scope.ViewModel.Rows[i];
var projectData = resourceData.Projects[projectRow.Id];
var expenditureCategoryId = (!projectRow.IsMultipleECs && projectRow.ExpenditureCategoryId && projectRow.ExpenditureCategoryId.length) ? projectRow.ExpenditureCategoryId[0] : resourceData.OwnExpenditureCategoryId;
activityCalendarUIService.fillResourceRowWithData($scope.ViewModel.Header, null, expenditureCategoryId, $scope.Filter.EntityId, projectRow,
projectData, null, projectRow.ActiveScenario.StartDate, projectRow.ActiveScenario.EndDate, true, projectRow.DisableResourceEdit);
if (projectRow.Children && (projectRow.Children.length == 1)) {
// Fill Resource actuals row
var actualsRow = projectRow.Children[0];
activityCalendarUIService.fillResourceActualsRowWithData($scope.ViewModel.Header, actualsRow, projectData,
projectRow.ActiveScenario.StartDate, projectRow.ActiveScenario.EndDate, projectRow.DisableResourceEdit);
}
}
}
projectsByResourceCache = {};
// Fill NPT-rows with data and clear NPT caches. Caches not need more
fillNonProjectTimeRowsWithData();
nonProjectTimeCache = {};
nonProjectTimeCategoryCache = {};
// Fill total rows with data
fillTotalRowsWithData();
var endDate = new Date().getTime();
console.log('filling model with data: ' + (endDate - startDate) + ' ms');
};
function fillNonProjectTimeRowsWithData() {
activityCalendarUIService.fillTotalNptRowData($scope.ViewModel.NonProjectTimeTotalRow, nonProjectTimeCache[$scope.Filter.EntityId], $scope.ViewModel.Header);
};
function fillCurrentlyAssignedRowWithData() {
var rowsForCurrentlyAssigned = angular.copy($scope.ViewModel.Rows) || [];
activityCalendarUIService.fillTotalRowData(rowsForCurrentlyAssigned, $scope.ViewModel.CurrentlyAssignedRow, $scope.ViewModel.Header);
};
function fillActualTotalRowWithData() {
if (!$scope.ViewModel.TotalRow || !$scope.ViewModel.TotalRow.Children || !$scope.ViewModel.TotalRow.Children.length)
return;
var actualTotalRow = $scope.ViewModel.TotalRow.Children[0];
var projectRows = angular.copy($scope.ViewModel.Rows) || [];
var actualProjectRows = [];
for (var index = 0; index < projectRows.length; index++) {
var projectRow = projectRows[index];
if (projectRow.Children && projectRow.Children.length && (projectRow.Children[0].RowType == 'ProjectResourceActuals')) {
actualProjectRows.push(angular.copy(projectRow.Children[0]));
}
}
activityCalendarUIService.fillTotalRowData(actualProjectRows, actualTotalRow, $scope.ViewModel.Header);
};
function fillTotalRowsWithData() {
var startDate = new Date().getTime();
// Fill Currently Assigned row
fillCurrentlyAssignedRowWithData();
// Fill Total row (as CurrentlyAssigned + NPT)
var rowsForTotal = angular.copy($scope.ViewModel.Rows) || [];
rowsForTotal.push(angular.copy($scope.ViewModel.NonProjectTimeTotalRow));
activityCalendarUIService.fillTotalRowData(rowsForTotal, $scope.ViewModel.TotalRow, $scope.ViewModel.Header);
activityCalendarUIService.fillResourceRemainingCapacityRowData($scope.ViewModel.TotalRow,
$scope.ViewModel.RemainingCapacityRow, $scope.Filter.EntityId, $scope.ViewModel.Header);
// Fill Actual total row - a child row for Total
fillActualTotalRowWithData();
var endDate = new Date().getTime();
console.log('filling total rows with data: ' + (endDate - startDate) + ' ms');
};
/* Methods for toggling display modes */
function toggleHoursResourcesMode() {
var totalRows = getTotalRows();
activityCalendarUIService.toggleGridSource($scope.ViewModel.Rows, $scope.ViewModel.DisplayMode.IsUOMHours);
activityCalendarUIService.toggleGridSource(totalRows, $scope.ViewModel.DisplayMode.IsUOMHours);
if ($scope.ViewModel.DisplayMode.IsAvgMode()) {
activityCalendarUIService.applyAvgMode($scope.ViewModel.Rows, $scope.ViewModel.Header);
activityCalendarUIService.applyAvgMode(totalRows, $scope.ViewModel.Header);
}
};
function toggleBarsValuesMode() {
if (!$scope.ViewModel.Rows || !$scope.ViewModel.Rows.length) {
return;
}
activityCalendarUIService.toggleBarsValuesMode($scope.ViewModel.Rows, $scope.ViewModel.DisplayMode.IsBarMode);
for (var i = 0; i < $scope.ViewModel.Rows.length; i++) {
activityCalendarUIService.toggleBarsValuesMode($scope.ViewModel.Rows[i].Children, $scope.ViewModel.DisplayMode.IsBarMode);
}
};
function toggleMonths() {
if ($scope.ViewModel.DisplayMode.IsViewModeMonth) {
$scope.ViewModel.Header.collapseMonthes();
}
else {
$scope.ViewModel.Header.expandMonthes();
}
};
function toggleParts() {
if (!$scope.ViewModel.Visibility.ShowForecast)
return;
$scope.ViewModel.Rows = activityCalendarUIService.toggleParts($scope.ViewModel.Rows, $scope.ViewModel.DisplayMode.ShowParts.Value);
};
function toggleSortBy() {
$scope.ViewModel.Rows = activityCalendarUIService.toggleSortBy($scope.ViewModel.Rows, $scope.ViewModel.DisplayMode.SortBy, $scope.ViewModel.DisplayMode.SortOrder);
};
function toggleCapacityType() {
// reset total row values
createTotalRowModels();
// recalculate total row UI data
fillTotalRowsWithData();
toggleHoursResourcesMode();
};
function toggleSecurityMode() {
if (!$scope.ViewModel.Rows || !$scope.ViewModel.Rows.length)
return;
if (!$scope.ViewModel.Visibility.ShowForecast && !$scope.ViewModel.Visibility.ShowActuals) {
$scope.ViewModel.Rows = [];
return;
}
if (!$scope.ViewModel.Visibility.ShowActuals) {
for (var index = 0; index < $scope.ViewModel.Rows.length; index++) {
var projectRow = $scope.ViewModel.Rows[index];
if (projectRow) {
if (projectRow.IsMaster) {
if (projectRow.Children && angular.isArray(projectRow.Children))
for (var partIndex = 0; partIndex < projectRow.Children.length; partIndex++) {
var projectPartRow = projectRow.Children[partIndex];
projectPartRow.Children = [];
}
}
else {
projectRow.Children = [];
}
}
}
}
if (!$scope.ViewModel.Visibility.ShowForecast) {
for (var index = $scope.ViewModel.Rows.length - 1; index >= 0; index--) {
var projectRow = $scope.ViewModel.Rows[index];
if (projectRow && projectRow.Children && projectRow.Children.length) {
$scope.ViewModel.Rows[index] = projectRow.Children[0];
}
else {
$scope.ViewModel.Rows.splice(index, 1);
}
}
}
};
function refreshResourceStyles(data) {
if (typeof data !== 'object' || !angular.isArray(data)) {
return;
}
if ($scope.ViewModel.Rows && $scope.ViewModel.Rows.length) {
// Add master project rows to the collection of top-level rows
var rows = $scope.ViewModel.Rows;
for (var index = 0; index < $scope.ViewModel.Rows.length; index++) {
var currentRow = $scope.ViewModel.Rows[index];
if (currentRow.IsMaster && currentRow.Children) {
for (var partIndex = 0; partIndex < currentRow.Children.length; partIndex++) {
rows.push(currentRow.Children[partIndex]);
}
}
}
activityCalendarUIService.updateResourceStyles($scope.ViewModel.Header, $scope.Filter.EntityId, rows, data);
}
};
function updateTotalRows(data) {
if (typeof data !== 'object' || !angular.isArray(data)) {
return;
}
var header = $scope.ViewModel.Header,
isUOMHours = $scope.ViewModel.DisplayMode.IsUOMHours,
isAvgMode = $scope.ViewModel.DisplayMode.IsAvgMode();
for (var i = 0; i < data.length; i++) {
var cell = data[i];
var month = header.Months[cell.MonthIndex];
var monthWeeksCount = month.Childs.length;
var deltaResourceValue = hoursResourcesConverter.convertToResources(cell.ExpenditureCategoryId, cell.DeltaHoursValue);
if ($scope.ViewModel.CurrentlyAssignedRow) {
$scope.ViewModel.CurrentlyAssignedRow.QuantityHoursValues[cell.WeekIndex] = roundService.roundQuantity(($scope.ViewModel.CurrentlyAssignedRow.QuantityHoursValues[cell.WeekIndex] || 0) + (cell.DeltaHoursValue || 0));
$scope.ViewModel.CurrentlyAssignedRow.QuantityHoursValues[month.SelfIndexInWeeks] = roundService.roundQuantity(($scope.ViewModel.CurrentlyAssignedRow.QuantityHoursValues[month.SelfIndexInWeeks] || 0) + (cell.DeltaHoursValue || 0));
$scope.ViewModel.CurrentlyAssignedRow.TotalHoursValue = roundService.roundQuantity(($scope.ViewModel.CurrentlyAssignedRow.TotalHoursValue || 0) + (cell.DeltaHoursValue || 0));
$scope.ViewModel.CurrentlyAssignedRow.QuantityResourcesValues[cell.WeekIndex] = roundService.roundQuantity(($scope.ViewModel.CurrentlyAssignedRow.QuantityResourcesValues[cell.WeekIndex] || 0) + (deltaResourceValue || 0));
$scope.ViewModel.CurrentlyAssignedRow.QuantityResourcesValues[month.SelfIndexInWeeks] = roundService.roundQuantity(($scope.ViewModel.CurrentlyAssignedRow.QuantityResourcesValues[month.SelfIndexInWeeks] || 0) + (deltaResourceValue || 0));
$scope.ViewModel.CurrentlyAssignedRow.TotalResourcesValue = roundService.roundQuantity(($scope.ViewModel.CurrentlyAssignedRow.TotalResourcesValue || 0) + (deltaResourceValue || 0));
}
if ($scope.ViewModel.TotalRow) {
$scope.ViewModel.TotalRow.QuantityHoursValues[cell.WeekIndex] = roundService.roundQuantity(($scope.ViewModel.TotalRow.QuantityHoursValues[cell.WeekIndex] || 0) + (cell.DeltaHoursValue || 0));
$scope.ViewModel.TotalRow.QuantityHoursValues[month.SelfIndexInWeeks] = roundService.roundQuantity(($scope.ViewModel.TotalRow.QuantityHoursValues[month.SelfIndexInWeeks] || 0) + (cell.DeltaHoursValue || 0));
$scope.ViewModel.TotalRow.TotalHoursValue = roundService.roundQuantity(($scope.ViewModel.TotalRow.TotalHoursValue || 0) + (cell.DeltaHoursValue || 0));
$scope.ViewModel.TotalRow.QuantityResourcesValues[cell.WeekIndex] = roundService.roundQuantity(($scope.ViewModel.TotalRow.QuantityResourcesValues[cell.WeekIndex] || 0) + (deltaResourceValue || 0));
$scope.ViewModel.TotalRow.QuantityResourcesValues[month.SelfIndexInWeeks] = roundService.roundQuantity(($scope.ViewModel.TotalRow.QuantityResourcesValues[month.SelfIndexInWeeks] || 0) + (deltaResourceValue || 0));
$scope.ViewModel.TotalRow.TotalResourcesValue = roundService.roundQuantity(($scope.ViewModel.TotalRow.TotalResourcesValue || 0) + (deltaResourceValue || 0));
}
if ($scope.ViewModel.RemainingCapacityRow) {
$scope.ViewModel.RemainingCapacityRow.QuantityHoursValues[cell.WeekIndex] = roundService.roundQuantity(($scope.ViewModel.RemainingCapacityRow.QuantityHoursValues[cell.WeekIndex] || 0) - (cell.DeltaHoursValue || 0));
$scope.ViewModel.RemainingCapacityRow.QuantityHoursValues[month.SelfIndexInWeeks] = roundService.roundQuantity(($scope.ViewModel.RemainingCapacityRow.QuantityHoursValues[month.SelfIndexInWeeks] || 0) - (cell.DeltaHoursValue || 0));
$scope.ViewModel.RemainingCapacityRow.TotalHoursValue = roundService.roundQuantity(($scope.ViewModel.RemainingCapacityRow.TotalHoursValue || 0) - (cell.DeltaHoursValue || 0));
$scope.ViewModel.RemainingCapacityRow.QuantityResourcesValues[cell.WeekIndex] = roundService.roundQuantity(($scope.ViewModel.RemainingCapacityRow.QuantityResourcesValues[cell.WeekIndex] || 0) - (deltaResourceValue || 0));
$scope.ViewModel.RemainingCapacityRow.QuantityResourcesValues[month.SelfIndexInWeeks] = roundService.roundQuantity(($scope.ViewModel.RemainingCapacityRow.QuantityResourcesValues[month.SelfIndexInWeeks] || 0) - (deltaResourceValue || 0));
$scope.ViewModel.RemainingCapacityRow.TotalResourcesValue = roundService.roundQuantity(($scope.ViewModel.RemainingCapacityRow.TotalResourcesValue || 0) - (deltaResourceValue || 0));
}
if (isUOMHours) {
if ($scope.ViewModel.CurrentlyAssignedRow) {
$scope.ViewModel.CurrentlyAssignedRow.Cells[cell.WeekIndex] = $scope.ViewModel.CurrentlyAssignedRow.QuantityHoursValues[cell.WeekIndex];
$scope.ViewModel.CurrentlyAssignedRow.Cells[month.SelfIndexInWeeks] = $scope.ViewModel.CurrentlyAssignedRow.QuantityHoursValues[month.SelfIndexInWeeks];
$scope.ViewModel.CurrentlyAssignedRow.TotalValue = $scope.ViewModel.CurrentlyAssignedRow.TotalHoursValue;
}
if ($scope.ViewModel.TotalRow) {
$scope.ViewModel.TotalRow.Cells[cell.WeekIndex] = $scope.ViewModel.TotalRow.QuantityHoursValues[cell.WeekIndex];
$scope.ViewModel.TotalRow.Cells[month.SelfIndexInWeeks] = $scope.ViewModel.TotalRow.QuantityHoursValues[month.SelfIndexInWeeks];
$scope.ViewModel.TotalRow.TotalValue = $scope.ViewModel.TotalRow.TotalHoursValue;
}
if ($scope.ViewModel.RemainingCapacityRow) {
$scope.ViewModel.RemainingCapacityRow.Cells[cell.WeekIndex] = $scope.ViewModel.RemainingCapacityRow.QuantityHoursValues[cell.WeekIndex];
$scope.ViewModel.RemainingCapacityRow.Cells[month.SelfIndexInWeeks] = $scope.ViewModel.RemainingCapacityRow.QuantityHoursValues[month.SelfIndexInWeeks];
$scope.ViewModel.RemainingCapacityRow.TotalValue = $scope.ViewModel.RemainingCapacityRow.TotalHoursValue;
}
}
else {
if ($scope.ViewModel.CurrentlyAssignedRow) {
$scope.ViewModel.CurrentlyAssignedRow.Cells[cell.WeekIndex] = $scope.ViewModel.CurrentlyAssignedRow.QuantityResourcesValues[cell.WeekIndex];
$scope.ViewModel.CurrentlyAssignedRow.Cells[month.SelfIndexInWeeks] = isAvgMode ? roundService.roundQuantity($scope.ViewModel.CurrentlyAssignedRow.QuantityResourcesValues[month.SelfIndexInWeeks] / monthWeeksCount) : $scope.ViewModel.CurrentlyAssignedRow.QuantityResourcesValues[month.SelfIndexInWeeks];
$scope.ViewModel.CurrentlyAssignedRow.TotalValue = isAvgMode ? roundService.roundQuantity(($scope.ViewModel.CurrentlyAssignedRow.TotalResourcesValue / header.TotalWeeks)) : $scope.ViewModel.CurrentlyAssignedRow.TotalResourcesValue;
}
if ($scope.ViewModel.TotalRow) {
$scope.ViewModel.TotalRow.Cells[cell.WeekIndex] = $scope.ViewModel.TotalRow.QuantityResourcesValues[cell.WeekIndex];
$scope.ViewModel.TotalRow.Cells[month.SelfIndexInWeeks] = isAvgMode ? roundService.roundQuantity($scope.ViewModel.TotalRow.QuantityResourcesValues[month.SelfIndexInWeeks] / monthWeeksCount) : $scope.ViewModel.TotalRow.QuantityResourcesValues[month.SelfIndexInWeeks];
$scope.ViewModel.TotalRow.TotalValue = isAvgMode ? roundService.roundQuantity(($scope.ViewModel.TotalRow.TotalResourcesValue / header.TotalWeeks)) : $scope.ViewModel.TotalRow.TotalResourcesValue;
}
if ($scope.ViewModel.RemainingCapacityRow) {
$scope.ViewModel.RemainingCapacityRow.Cells[cell.WeekIndex] = $scope.ViewModel.RemainingCapacityRow.QuantityResourcesValues[cell.WeekIndex];
$scope.ViewModel.RemainingCapacityRow.Cells[month.SelfIndexInWeeks] = isAvgMode ? roundService.roundQuantity(($scope.ViewModel.RemainingCapacityRow.QuantityResourcesValues[month.SelfIndexInWeeks] / monthWeeksCount)) : $scope.ViewModel.RemainingCapacityRow.QuantityResourcesValues[month.SelfIndexInWeeks];
$scope.ViewModel.RemainingCapacityRow.TotalValue = isAvgMode ? roundService.roundQuantity(($scope.ViewModel.RemainingCapacityRow.TotalResourcesValue / header.TotalWeeks)) : $scope.ViewModel.RemainingCapacityRow.TotalResourcesValue;
}
}
}
};
function updateActualTotalRow(data) {
if (typeof data !== 'object' || !angular.isArray(data)) {
return;
}
var header = $scope.ViewModel.Header,
isUOMHours = $scope.ViewModel.DisplayMode.IsUOMHours,
isAvgMode = $scope.ViewModel.DisplayMode.IsAvgMode();
var actualTotalRow = null;
if ($scope.ViewModel.TotalRow && $scope.ViewModel.TotalRow.Children && $scope.ViewModel.TotalRow.Children.length) {
actualTotalRow = $scope.ViewModel.TotalRow.Children[0];
}
if (!actualTotalRow)
return;
for (var i = 0; i < data.length; i++) {
var cell = data[i];
var month = header.Months[cell.MonthIndex];
var monthWeeksCount = month.Childs.length;
var deltaResourceValue = hoursResourcesConverter.convertToResources(cell.ExpenditureCategoryId, cell.DeltaHoursValue);
actualTotalRow.QuantityHoursValues[cell.WeekIndex] = roundService.roundQuantity((actualTotalRow.QuantityHoursValues[cell.WeekIndex] || 0) + (cell.DeltaHoursValue || 0));
actualTotalRow.QuantityHoursValues[month.SelfIndexInWeeks] = roundService.roundQuantity((actualTotalRow.QuantityHoursValues[month.SelfIndexInWeeks] || 0) + (cell.DeltaHoursValue || 0));
actualTotalRow.TotalHoursValue = roundService.roundQuantity((actualTotalRow.TotalHoursValue || 0) + (cell.DeltaHoursValue || 0));
actualTotalRow.QuantityResourcesValues[cell.WeekIndex] = roundService.roundQuantity((actualTotalRow.QuantityResourcesValues[cell.WeekIndex] || 0) + (deltaResourceValue || 0));
actualTotalRow.QuantityResourcesValues[month.SelfIndexInWeeks] = roundService.roundQuantity((actualTotalRow.QuantityResourcesValues[month.SelfIndexInWeeks] || 0) + (deltaResourceValue || 0));
actualTotalRow.TotalResourcesValue = roundService.roundQuantity((actualTotalRow.TotalResourcesValue || 0) + (deltaResourceValue || 0));
if (isUOMHours) {
actualTotalRow.Cells[cell.WeekIndex] = actualTotalRow.QuantityHoursValues[cell.WeekIndex];
actualTotalRow.Cells[month.SelfIndexInWeeks] = actualTotalRow.QuantityHoursValues[month.SelfIndexInWeeks];
actualTotalRow.TotalValue = actualTotalRow.TotalHoursValue;
}
else {
actualTotalRow.Cells[cell.WeekIndex] = actualTotalRow.QuantityResourcesValues[cell.WeekIndex];
actualTotalRow.Cells[month.SelfIndexInWeeks] = isAvgMode ? roundService.roundQuantity(actualTotalRow.QuantityResourcesValues[month.SelfIndexInWeeks] / monthWeeksCount) : actualTotalRow.QuantityResourcesValues[month.SelfIndexInWeeks];
actualTotalRow.TotalValue = isAvgMode ? roundService.roundQuantity(actualTotalRow.TotalResourcesValue / header.TotalWeeks) : actualTotalRow.TotalResourcesValue;
}
}
};
function updateProjectRows(data, projectId) {
if (!projectId || (typeof data !== 'object') || !angular.isArray(data)) {
return;
}
var projectRows = activityCalendarUIService.getProjectRows($scope.ViewModel.Rows, projectId);
if (!projectRows || !projectRows.masterProjectRow)
return;
var header = $scope.ViewModel.Header,
isUOMHours = $scope.ViewModel.DisplayMode.IsUOMHours,
isAvgMode = $scope.ViewModel.DisplayMode.IsAvgMode();
var row = projectRows.masterProjectRow;
for (var i = 0; i < data.length; i++) {
var cell = data[i];
var month = header.Months[cell.MonthIndex];
var monthWeeksCount = month.Childs.length;
var deltaResourceValue = hoursResourcesConverter.convertToResources(cell.ExpenditureCategoryId, cell.DeltaHoursValue);
row.QuantityHoursValues[cell.WeekIndex] = roundService.roundQuantity((row.QuantityHoursValues[cell.WeekIndex] || 0) + (cell.DeltaHoursValue || 0));
row.QuantityHoursValues[month.SelfIndexInWeeks] = roundService.roundQuantity((row.QuantityHoursValues[month.SelfIndexInWeeks] || 0) + (cell.DeltaHoursValue || 0));
row.TotalHoursValue = roundService.roundQuantity((row.TotalHoursValue || 0) + (cell.DeltaHoursValue || 0));
row.QuantityResourcesValues[cell.WeekIndex] = roundService.roundQuantity((row.QuantityResourcesValues[cell.WeekIndex] || 0) + (deltaResourceValue || 0));
row.QuantityResourcesValues[month.SelfIndexInWeeks] = roundService.roundQuantity((row.QuantityResourcesValues[month.SelfIndexInWeeks] || 0) + (deltaResourceValue || 0));
row.TotalResourcesValue = roundService.roundQuantity((row.TotalResourcesValue || 0) + (deltaResourceValue || 0));
if (isUOMHours) {
row.Cells[cell.WeekIndex] = row.QuantityHoursValues[cell.WeekIndex];
row.Cells[month.SelfIndexInWeeks] = row.QuantityHoursValues[month.SelfIndexInWeeks];
row.TotalValue = row.TotalHoursValue;
}
else {
row.Cells[cell.WeekIndex] = row.QuantityResourcesValues[cell.WeekIndex];
row.Cells[month.SelfIndexInWeeks] = isAvgMode ? roundService.roundQuantity(row.QuantityResourcesValues[month.SelfIndexInWeeks] / monthWeeksCount) : row.QuantityResourcesValues[month.SelfIndexInWeeks];
row.TotalValue = isAvgMode ? roundService.roundQuantity(row.TotalResourcesValue / header.TotalWeeks) : row.TotalResourcesValue;
}
}
};
}]);