747 lines
33 KiB
JavaScript
747 lines
33 KiB
JavaScript
'use strict';
|
|
|
|
app.controller('capacityManagementController', ['$scope', '$timeout', '$q', '$document', '$element', 'activityCalendarService', 'activityCalendarUIService', function ($scope, $timeout, $q, $document, $element, activityCalendarService, activityCalendarUIService) {
|
|
var updateFilterOptionsUrl = '/CapacityManagement/GetFilterOptions';
|
|
// $scope.EntityType replaced in code with activityCalendarUIService.filterEntityType enum,
|
|
// because it is used both in controller and in AC UI services
|
|
// $scope.EntityType leaved here for html view
|
|
$scope.EntityType = {
|
|
Team: 1,
|
|
View: 2,
|
|
Company: 3,
|
|
Resource: 4,
|
|
};
|
|
$scope.GroupByMode = {
|
|
None: '0', // Special grouping mode for resource calendar
|
|
Team: '1',
|
|
Project: '2',
|
|
Resource: '3',
|
|
Company: '4',
|
|
Client: '5',
|
|
CostCenter: '6',
|
|
};
|
|
$scope.SortByMode = {
|
|
Name: 'Name',
|
|
Type: 'Type',
|
|
Date: 'Date',
|
|
Priority: 'Priority'
|
|
};
|
|
var defaultGroupByItems = [
|
|
{ value: $scope.GroupByMode.Project, text: 'Project' },
|
|
{ value: $scope.GroupByMode.Company, text: 'Business Unit' },
|
|
{ value: $scope.GroupByMode.Client, text: 'Client' },
|
|
{ value: $scope.GroupByMode.CostCenter, text: 'Cost Center' },
|
|
{ value: $scope.GroupByMode.Team, text: 'Team' },
|
|
{ value: $scope.GroupByMode.Resource, text: 'Resource' }
|
|
];
|
|
$scope.SortByItems = [
|
|
{ value: $scope.SortByMode.Name, text: 'Name' },
|
|
{ value: $scope.SortByMode.Type, text: 'Type' },
|
|
{ value: $scope.SortByMode.Date, text: 'Date' },
|
|
{ value: $scope.SortByMode.Priority, text: 'Priority' }
|
|
];
|
|
$scope.Templates = {};
|
|
$scope.Templates[$scope.GroupByMode.Project] = '/Content/templates/ActivityCalendar/_activityCalendar.html?v=' + new Date().getTime();
|
|
$scope.Templates[$scope.GroupByMode.Team] = '/Content/templates/ActivityCalendar/_activityCalendarByTeam.html?v=' + new Date().getTime();
|
|
$scope.Templates[$scope.GroupByMode.Resource] = '/Content/templates/ActivityCalendar/_activityCalendarByResource.html?v=' + new Date().getTime();
|
|
$scope.Templates[$scope.GroupByMode.Company] = '/Content/templates/ActivityCalendar/_activityCalendarByCompany.html?v=' + new Date().getTime();
|
|
$scope.Templates[$scope.GroupByMode.Client] = '/Content/templates/ActivityCalendar/_activityCalendarByClient.html?v=' + new Date().getTime();
|
|
$scope.Templates[$scope.GroupByMode.CostCenter] = '/Content/templates/ActivityCalendar/_activityCalendarByCostCenter.html?v=' + new Date().getTime();
|
|
// Template for Resource Calendar - displayed with no grouping
|
|
$scope.Templates[$scope.GroupByMode.None] = '/Content/templates/ActivityCalendar/_resourceCalendar.html?v=' + new Date().getTime();
|
|
|
|
$scope.EntityFilterOptions = {};
|
|
$scope.AvailableFilterOptions = {};
|
|
|
|
$scope.DisplayMode = {
|
|
IsViewModeMonth: false,
|
|
IsUOMHours: false,
|
|
ShowAvgTotals: false,
|
|
GroupByItems: defaultGroupByItems,
|
|
GroupBy: {
|
|
Value: defaultGroupByItems[0].value,
|
|
Hide: false,
|
|
Disabled: false
|
|
},
|
|
CapacityMode: {
|
|
Value: '1',
|
|
Hide: false,
|
|
Disabled: false
|
|
},
|
|
CalendarView: null,
|
|
CapacityView: {
|
|
Value: '1',
|
|
Hide: false,
|
|
Disabled: false
|
|
},
|
|
ShowParts: {
|
|
Value: true,
|
|
Hide: false,
|
|
Disabled: false
|
|
},
|
|
PageKey: null,
|
|
MenuId: null,
|
|
DataSection: null,
|
|
ShowUpper: {
|
|
Value: true,
|
|
Hide: false,
|
|
Disabled: false
|
|
},
|
|
ShowLower: {
|
|
Value: true,
|
|
Hide: false,
|
|
Disabled: false
|
|
},
|
|
IsBarMode: false,
|
|
IsCapacityModeActuals: {
|
|
Value: true,
|
|
Hide: false,
|
|
Disabled: false
|
|
},
|
|
SortBy: $scope.SortByItems[0].value,
|
|
SortOrder: null,
|
|
IsAvgMode: function () {
|
|
return !this.IsUOMHours && this.ShowAvgTotals;
|
|
},
|
|
BackUrlTitle: null
|
|
};
|
|
$scope.Filter = {
|
|
EntityType: null,
|
|
EntityId: null,
|
|
StartDate: null,
|
|
EndDate: null,
|
|
ShowFilters: true,
|
|
FilteredEntityTitle: '',
|
|
CostCenters: null,
|
|
ProjectRoles: null
|
|
};
|
|
|
|
// Indicates, calendar has unsaved changes
|
|
$scope.CalendarDataChanged = false;
|
|
|
|
//workflow commands
|
|
$scope.WorkFlowActions = [{ ScenarioId: null, ProjectName: null, Commands: [{ command: null, Selected: false }], HasChanges: false }];
|
|
// event listeners
|
|
$scope.$on('ac.calendarDataChanged', function (event) {
|
|
// Occurs, when user changed calendar data
|
|
$scope.CalendarDataChanged = activityCalendarService.isDataChanged($scope.Filter);
|
|
});
|
|
$scope.$on('ac.calendarDataChangesCancelled', function (event) {
|
|
// Occurs, when user chancelled changes of calendar data
|
|
$scope.CalendarDataChanged = false;
|
|
});
|
|
$scope.$on('ac.workflowactionsloaded', function (event) {
|
|
$scope.WorkFlowActions = activityCalendarService.getWorkFlowActions();
|
|
});
|
|
// event handlers
|
|
$scope.onPageOptionChange = function (e, key, newValue) {
|
|
updatePagePreferenceValueAsync($scope.DisplayMode.PageKey, $scope.DisplayMode.DataSection, key, newValue);
|
|
switch (key) {
|
|
case 'capacityFilterStartDate':
|
|
case 'capacityFilterEndDate':
|
|
break;
|
|
case 'groupBy':
|
|
break;
|
|
default:
|
|
$scope.onOptionsChanged(key, newValue);
|
|
break;
|
|
};
|
|
};
|
|
$scope.init = function (ctrlOptions) {
|
|
try {
|
|
blockUI();
|
|
var ctrlScope = $scope;
|
|
// Init $scope.DisplayMode options to be able to use provided options in UI directives
|
|
// otherwise UI directive will be inited before page options will be set from user preferences
|
|
// because promise callbacks will be handled in another digest.
|
|
// Review ability to add init event to UI directives to be able to have control over init process in them
|
|
$scope.DisplayMode = angular.extend({}, $scope.DisplayMode, ctrlOptions.DisplayMode);
|
|
$scope.Filter = angular.extend({}, $scope.Filter, ctrlOptions.Filter);
|
|
var filterOptionsTask = activityCalendarService.loadACFilterOptionsAsync(updateFilterOptionsUrl);
|
|
|
|
var preferencesTask = loadUserPagePreferencesAsync(ctrlOptions.DisplayMode.DataSection, $scope.DisplayMode.PageKey);
|
|
$q.all([filterOptionsTask, preferencesTask])
|
|
.then(function (asyncResults) {
|
|
ctrlScope.AvailableFilterOptions = asyncResults[0];
|
|
|
|
if (ctrlScope.AvailableFilterOptions.ProjectRoles) {
|
|
// Make initially all project roles visible for selection
|
|
ctrlScope.AvailableFilterOptions.ProjectRolesVisible = ctrlScope.AvailableFilterOptions.ProjectRoles;
|
|
}
|
|
|
|
var usrUOMModeTask = getDataSectionOptions(_USR_PREF_ISHOURS_KEY);
|
|
var usrAvgModeTask = getDataSectionOptions(_USR_PREF_AVG_KEY);
|
|
applyPagePreferences(ctrlOptions, asyncResults[1], usrUOMModeTask, usrAvgModeTask);
|
|
applyFilterMode(true);
|
|
setProjectRolesVisibility();
|
|
|
|
unblockUI();
|
|
})
|
|
.then(null, function () {
|
|
unblockUI();
|
|
showErrorModal(null, null, '000005');
|
|
});
|
|
}
|
|
catch (e) {
|
|
console.error(e);
|
|
unblockUI();
|
|
showErrorModal(null, null, '000006');
|
|
}
|
|
};
|
|
function applyPagePreferences(initOptions, pagePrefArray, userDefaultUOMMode, userDefaultAvgMode) {
|
|
var prefOptions = {};
|
|
var prefFilter = {};
|
|
|
|
prefFilter.CostCenters = [];
|
|
|
|
for (var i = 0; i < pagePrefArray.length; i++) {
|
|
switch (pagePrefArray[i].Key) {
|
|
case "showChart":
|
|
prefOptions.ShowUpper = {
|
|
Value: pagePrefArray[i].Value,
|
|
Hide: false,
|
|
Disabled: false
|
|
};
|
|
break;
|
|
case "showCriteria":
|
|
prefOptions.ShowLower = {
|
|
Value: pagePrefArray[i].Value,
|
|
Hide: false,
|
|
Disabled: false
|
|
}
|
|
break;
|
|
case "showOption":
|
|
prefOptions.CapacityMode = {
|
|
Value: pagePrefArray[i].Value,
|
|
Hide: false,
|
|
Disabled: false
|
|
};
|
|
break;
|
|
case "CapacityMode":
|
|
if (!prefOptions.CapacityMode)
|
|
prefOptions.CapacityMode = {
|
|
Value: '0',
|
|
Hide: false,
|
|
Disabled: false
|
|
};
|
|
|
|
prefOptions.CapacityMode.Value = pagePrefArray[i].Value;
|
|
break;
|
|
case "uomMode":
|
|
if (!isNaN(pagePrefArray[i].Value))
|
|
prefOptions.IsUOMHours = pagePrefArray[i].Value;
|
|
else
|
|
prefOptions.IsUOMHours = Object.parseBoolean(userDefaultUOMMode);
|
|
break;
|
|
case "capBarMode":
|
|
prefOptions.IsBarMode = pagePrefArray[i].Value;
|
|
break;
|
|
case "defaultView":
|
|
prefOptions.IsViewModeMonth = pagePrefArray[i].Value;
|
|
break;
|
|
case "groupByTeam": // obsolete, remains for compatibility with old data
|
|
if (!prefOptions.GroupBy) {
|
|
prefOptions.GroupBy = {
|
|
Value: pagePrefArray[i].Value ? $scope.GroupByMode.Team : $scope.GroupByMode.Project,
|
|
Hide: false,
|
|
Disabled: false
|
|
};
|
|
prefOptions.CalendarView = $scope.Templates[prefOptions.GroupBy.Value];
|
|
}
|
|
break;
|
|
case "groupBy":
|
|
prefOptions.GroupBy = {
|
|
Value: pagePrefArray[i].Value,
|
|
Hide: false,
|
|
Disabled: false
|
|
};
|
|
if (prefOptions.GroupBy != null && prefOptions.GroupBy.Value != null)
|
|
prefOptions.CalendarView = $scope.Templates[prefOptions.GroupBy.Value];
|
|
break;
|
|
case "capacityView":
|
|
prefOptions.IsCapacityModeActuals = {
|
|
Value: pagePrefArray[i].Value,
|
|
Hide: false,
|
|
Disabled: false
|
|
};
|
|
break;
|
|
case "showParts":
|
|
prefOptions.ShowParts = {
|
|
Value: pagePrefArray[i].Value,
|
|
Hide: false,
|
|
Disabled: false
|
|
};
|
|
break;
|
|
case "capacityFilterStartDate":
|
|
// do not override settings received in ng-init
|
|
if ($scope.Filter.StartDate == null)
|
|
prefFilter.StartDate = pagePrefArray[i].Value;
|
|
break;
|
|
case "capacityFilterEndDate":
|
|
// do not override settings received in ng-init
|
|
if ($scope.Filter.EndDate == null)
|
|
prefFilter.EndDate = pagePrefArray[i].Value;
|
|
break;
|
|
case "filterCompanyList": // obsolete, remains for compatibility with old data
|
|
// do not override settings received in ng-init
|
|
if ((pagePrefArray[i].Value) && (!$scope.Filter.EntityType) && !prefFilter.EntityType)
|
|
prefFilter.EntityType = activityCalendarUIService.filterEntityType.company; // $scope.EntityType.Company;
|
|
break;
|
|
case "filterViewList": // obsolete, remains for compatibility with old data
|
|
// do not override settings received in ng-init
|
|
if ((pagePrefArray[i].Value) && (!$scope.Filter.EntityType) && !prefFilter.EntityType)
|
|
prefFilter.EntityType = activityCalendarUIService.filterEntityType.view; // $scope.EntityType.View;
|
|
break;
|
|
case "filterTeamList": // obsolete, remains for compatibility with old data
|
|
// do not override settings received in ng-init
|
|
if ((pagePrefArray[i].Value) && (!$scope.Filter.EntityType) && !prefFilter.EntityType)
|
|
prefFilter.EntityType = activityCalendarUIService.filterEntityType.team; // $scope.EntityType.Team;
|
|
break;
|
|
case "filterType":
|
|
// do not override settings received in ng-init
|
|
if ($scope.Filter.EntityType == null)
|
|
prefFilter.EntityType = pagePrefArray[i].Value;
|
|
break;
|
|
case "filteredCompany":
|
|
// do not override settings received in ng-init
|
|
if ($scope.Filter.EntityId == null)
|
|
prefFilter.EntityId = pagePrefArray[i].Value;
|
|
break;
|
|
case "filterCostCenters":
|
|
// do not override settings received in ng-init
|
|
if (pagePrefArray[i].Value && angular.isArray(pagePrefArray[i].Value) &&
|
|
(!$scope.Filter.CostCenters || !angular.isArray($scope.Filter.CostCenters) || !$scope.Filter.CostCenters.length))
|
|
prefFilter.CostCenters = pagePrefArray[i].Value;
|
|
break;
|
|
case "filterProjectRoles":
|
|
// do not override settings received in ng-init
|
|
if (pagePrefArray[i].Value && angular.isArray(pagePrefArray[i].Value) &&
|
|
(!$scope.Filter.ProjectRoles || !angular.isArray($scope.Filter.ProjectRoles) || !$scope.Filter.ProjectRoles.length))
|
|
prefFilter.ProjectRoles = pagePrefArray[i].Value;
|
|
break;
|
|
case "sortBy":
|
|
prefOptions.SortBy = pagePrefArray[i].Value;
|
|
break;
|
|
case "sortOrder":
|
|
prefOptions.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 + ")");
|
|
}
|
|
}
|
|
prefOptions.ShowAvgTotals = Object.parseBoolean(userDefaultAvgMode);
|
|
// set controller options by overriding controller defaults with page preferences and then with options specified in ng-init
|
|
// priority: ng-init options > page pref options > controller defaults
|
|
$scope.DisplayMode = angular.extend({}, $scope.DisplayMode, prefOptions, initOptions.DisplayMode);
|
|
|
|
// set controller filter by overriding controller defaults with page preferences and then with options specified in ng-init
|
|
// priority: ng-init options > page pref options > controller defaults
|
|
$scope.Filter = angular.extend({}, $scope.Filter, prefFilter);
|
|
|
|
if ($scope.DisplayMode.CalendarView == null && $scope.DisplayMode.GroupBy != null)
|
|
$scope.DisplayMode.CalendarView = $scope.Templates[$scope.DisplayMode.GroupBy.Value];
|
|
|
|
// do not allow both ShowUpper and ShowBottom to be disabled
|
|
if (!$scope.DisplayMode.ShowUpper.Value && !$scope.DisplayMode.ShowUpper.Hide) {
|
|
$scope.DisplayMode.ShowLower.Disabled = true;
|
|
}
|
|
if (!$scope.DisplayMode.ShowLower.Value && !$scope.DisplayMode.ShowLower.Hide) {
|
|
if ($scope.DisplayMode.ShowUpper.Value)
|
|
$scope.DisplayMode.ShowUpper.Disabled = true;
|
|
}
|
|
};
|
|
|
|
// ui methods
|
|
$scope.ngIncludeLoaded = function () {
|
|
//console.log('capacityManagementController.ngIncludeLoaded: ' + $scope.DisplayMode.CalendarView);
|
|
$scope.rebuildCalendar();
|
|
};
|
|
$scope.rebuildCalendar = function (forceDataReload) {
|
|
//console.log('capacityManagementController.rebuildCalendar: ' + $scope.DisplayMode.CalendarView);
|
|
if (!$scope.filterValid())
|
|
return;
|
|
|
|
$timeout(function () { // broadcast event in next digest to let angular to reload template if necessary in current digest
|
|
//console.log('capacityManagementController.broadcast ac.rebuild-calendar event: ' + $scope.DisplayMode.CalendarView);
|
|
$scope.$broadcast('ac.rebuild-calendar', $scope.Filter, $scope.DisplayMode, forceDataReload, function (data) {
|
|
$scope.CalendarDataChanged = activityCalendarService.isDataChanged($scope.Filter);
|
|
// Update client-side filter options
|
|
updateClientSideFilterOptions(data);
|
|
});
|
|
});
|
|
};
|
|
$scope.onOptionsChanged = function (key, value) {
|
|
//console.log('capacityManagementController.onOptionsChanged: ' + $scope.DisplayMode.CalendarView);
|
|
if (!$scope.filterValid())
|
|
return;
|
|
|
|
blockUI();
|
|
$timeout(function () {
|
|
$scope.$broadcast('ac.options-changed', $scope.DisplayMode, key, value);
|
|
unblockUI();
|
|
}, 200);
|
|
};
|
|
$scope.switchFilterMode = function () {
|
|
updatePagePreferenceValueAsync($scope.DisplayMode.PageKey, $scope.DisplayMode.DataSection, 'filterType', $scope.Filter.EntityType);
|
|
|
|
$scope.Filter.EntityId = null;
|
|
updatePagePreferenceEntityIdAsync();
|
|
|
|
applyFilterMode();
|
|
};
|
|
function applyFilterMode(preserverSelection) {
|
|
switch ($scope.Filter.EntityType) {
|
|
case activityCalendarUIService.filterEntityType.company: // $scope.EntityType.Company:
|
|
$scope.Filter.FilteredEntityTitle = "Business Unit";
|
|
if (($scope.AvailableFilterOptions != null) && ($scope.AvailableFilterOptions.Companies != null)) {
|
|
$scope.EntityFilterOptions = $scope.AvailableFilterOptions.Companies;
|
|
for (var i = 0; i < $scope.EntityFilterOptions.length; i++) {
|
|
var option = $scope.EntityFilterOptions[i];
|
|
option.CSSClass = 'ddl-level-item-ac';
|
|
if (option.Group && option.Group.Name && option.Group.Name.length > 0) {
|
|
option.CSSClass += ' pad-left';
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case activityCalendarUIService.filterEntityType.view: // $scope.EntityType.View:
|
|
$scope.Filter.FilteredEntityTitle = "View";
|
|
if (($scope.AvailableFilterOptions != null) && ($scope.AvailableFilterOptions.Views != null))
|
|
$scope.EntityFilterOptions = $scope.AvailableFilterOptions.Views;
|
|
break;
|
|
case activityCalendarUIService.filterEntityType.resource:
|
|
$scope.Filter.FilteredEntityTitle = "Resource";
|
|
$scope.EntityFilterOptions = [{ Value: $scope.Filter.EntityId, Text: '' }];
|
|
break;
|
|
case activityCalendarUIService.filterEntityType.team: // $scope.EntityType.Team:
|
|
default:
|
|
$scope.Filter.FilteredEntityTitle = "Team";
|
|
if (($scope.AvailableFilterOptions != null) && ($scope.AvailableFilterOptions.Teams != null))
|
|
$scope.EntityFilterOptions = $scope.AvailableFilterOptions.Teams;
|
|
break;
|
|
}
|
|
// use case: user filtered AC by team that was deleted later, so does not exist in the FilterOptions, but EntityId contains old team id
|
|
var entityIdExistsInTheList = false;
|
|
if ($scope.Filter.EntityId && $scope.EntityFilterOptions) {
|
|
for (var index = 0; index < $scope.EntityFilterOptions.length; index++) {
|
|
var element = $scope.EntityFilterOptions[index];
|
|
|
|
if (element && element.Value == $scope.Filter.EntityId) {
|
|
entityIdExistsInTheList = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!preserverSelection || !entityIdExistsInTheList) {
|
|
$scope.Filter.EntityId = null;
|
|
}
|
|
}
|
|
$scope.SelectedFilterElementChanged = function () {
|
|
updatePagePreferenceEntityIdAsync();
|
|
$scope.rebuildCalendar(true);
|
|
};
|
|
$scope.SelectedFilterCostCentersChanged = function () {
|
|
setProjectRolesVisibility();
|
|
updatePagePreferenceValueAsync($scope.DisplayMode.PageKey, $scope.DisplayMode.DataSection, 'filterCostCenters', $scope.Filter.CostCenters);
|
|
$scope.rebuildCalendar(false);
|
|
};
|
|
$scope.SelectedFilterProjectRolesChanged = function () {
|
|
updatePagePreferenceValueAsync($scope.DisplayMode.PageKey, $scope.DisplayMode.DataSection, 'filterProjectRoles', $scope.Filter.ProjectRoles);
|
|
$scope.rebuildCalendar(false);
|
|
};
|
|
$scope.changeCapacityMode = function () {
|
|
$scope.$broadcast('totalsAsChanged', $scope.DisplayMode.CapacityMode.Value);
|
|
};
|
|
$scope.changeGroupBy = function () {
|
|
$scope.DisplayMode.CalendarView = $scope.Templates[$scope.DisplayMode.GroupBy.Value];
|
|
};
|
|
$scope.filterValid = function () {
|
|
return $scope.Filter.EntityType && $scope.Filter.EntityId && $scope.Filter.StartDate && $scope.Filter.EndDate && $scope.DisplayMode.CalendarView
|
|
&& new Date($scope.Filter.EndDate) > new Date($scope.Filter.StartDate);
|
|
};
|
|
$scope.switchUpperPart = function () {
|
|
if (!$scope.DisplayMode.ShowUpper.Value) {
|
|
$scope.DisplayMode.ShowLower.Value = true;
|
|
}
|
|
$scope.DisplayMode.ShowLower.Disabled = !$scope.DisplayMode.ShowUpper.Value && !$scope.DisplayMode.ShowUpper.Hide;
|
|
};
|
|
$scope.switchLowerPart = function () {
|
|
if (!$scope.DisplayMode.ShowLower.Value) {
|
|
$scope.DisplayMode.ShowUpper.Value = true;
|
|
}
|
|
$scope.DisplayMode.ShowUpper.Disabled = !$scope.DisplayMode.ShowLower.Value && !$scope.DisplayMode.ShowLower.Hide;
|
|
$scope.$broadcast('showResourcesChanged', $scope.DisplayMode.ShowLower.Value);
|
|
};
|
|
|
|
/* Save changes dialog ------------------------------ */
|
|
$scope.SaveChangesDialog = {
|
|
SaveAction: 0, // Update current scenario
|
|
ScenarioName: "",
|
|
SetActive: true, // Save as active
|
|
ScenarioType: '0', // Keep current scenario type
|
|
// Form state variables
|
|
ShowValidationSummary: false, // Indicates whether to display validation summary message or not
|
|
ProjectsWithSuperExpenditures: [], // List of changed projects, containing super expenditures
|
|
ChangedProjects: [], // list of all changed projects
|
|
WorkFlowActions: $scope.WorkFlowActions
|
|
};
|
|
$scope.saveChanges = function () {
|
|
// Init save changes form
|
|
$scope.prepareWorkFlowOptionsBeforeSaving();
|
|
$scope.SaveChangesDialog.SaveAction = 0; // Update current scenario
|
|
$scope.SaveChangesDialog.ScenarioName = "";
|
|
$scope.SaveChangesDialog.SetActive = true; // Save as active
|
|
$scope.SaveChangesDialog.ScenarioType = '0'; // Keep current scenario type
|
|
// Form state variables
|
|
$scope.SaveChangesDialog.ShowValidationSummary = false; // Indicates whether to display validation summary message or not
|
|
$scope.SaveChangesDialog.ProjectsWithSuperExpenditures = []; // List of changed projects, containing super expenditures
|
|
$scope.SaveChangesDialog.ChangedProjects = [];
|
|
$scope.SaveChangesDialog.WorkFlowActions = $scope.WorkFlowActions;
|
|
// Get calendar projects, that contains Super ECs
|
|
$scope.SaveChangesDialog.ProjectsWithSuperExpenditures =
|
|
activityCalendarService.getChangedProjectsWithSuperECs($scope.Filter);
|
|
var changedData = activityCalendarService.getProjectsFromSaveModel($scope.Filter);
|
|
angular.forEach(changedData, function (prjItem, prjKey) {
|
|
// set checkbox checked for BU scenarios on initial form load
|
|
prjItem.UpdateProjections = prjItem.IsBottomUp;
|
|
// setup UI properties
|
|
fillSaveProjectUIModel(prjItem);
|
|
|
|
$scope.SaveChangesDialog.ChangedProjects.push(prjItem);
|
|
});
|
|
validateSaveProjects();
|
|
|
|
$scope.$broadcast('ac.show-save-dialog');
|
|
};
|
|
$scope.prepareWorkFlowOptionsBeforeSaving = function () {
|
|
|
|
var calendarData = activityCalendarService.getActivityCalendarSaveModel($scope.Filter);
|
|
|
|
if (!calendarData)
|
|
return;
|
|
$.each(calendarData.Scenarios, function (scenarioId, scenario) {
|
|
|
|
setWorkFlowActions(scenarioId, true);
|
|
});
|
|
}
|
|
function setWorkFlowActions(scenarioId, hasCange) {
|
|
var i = 0;
|
|
var len = $scope.WorkFlowActions.length;
|
|
for (; i < len; i++) {
|
|
if ($scope.WorkFlowActions[i].ScenarioId == scenarioId) {
|
|
$scope.WorkFlowActions[i].HasChanges = hasCange;
|
|
return;
|
|
}
|
|
else if ($scope.WorkFlowActions[i].ScenarioId == null){
|
|
$scope.WorkFlowActions[i].ScenarioId=C_EMPTY_GUID;
|
|
}
|
|
}
|
|
}
|
|
$scope.WorkFlowChanges = function () {
|
|
var i = 0;
|
|
var len = $scope.WorkFlowActions.length;
|
|
for (; i < len; i++) {
|
|
if ($scope.WorkFlowActions[i].HasChanges) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
$scope.updateWorkFlowOption = function ($scope2) {
|
|
var i = 0;
|
|
var len = $scope.WorkFlowActions.length;
|
|
for (; i < len; i++) {
|
|
if ($scope.WorkFlowActions[i].ScenarioId == $scope2.Id) {
|
|
var len2 = $scope.WorkFlowActions[i].Commands.length;
|
|
var j = 0;
|
|
for (; j < len2; j++) {
|
|
if ($scope.WorkFlowActions[i].Commands[j].command == $scope2.command) {
|
|
$scope.WorkFlowActions[i].Commands[j].Selected = true;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
$scope.saveChangesConfirmed = function (formIsValid) {
|
|
if (!formIsValid)
|
|
return false;
|
|
|
|
var calendarData = activityCalendarService.getActivityCalendarSaveModel($scope.Filter);
|
|
if (!calendarData)
|
|
return false;
|
|
|
|
var model = angular.copy(calendarData);
|
|
// set UpdateProjections flag for scenarios based on switcher values entered in Save Changes form
|
|
for (var i = 0; i < $scope.SaveChangesDialog.ChangedProjects.length; i++) {
|
|
var projSaveModel = $scope.SaveChangesDialog.ChangedProjects[i];
|
|
var projCalendarModel = model.Scenarios[projSaveModel.ScenarioId];
|
|
if (projCalendarModel) {
|
|
projCalendarModel.UpdateProjections = projSaveModel.UpdateProjections;
|
|
}
|
|
}
|
|
// Fill data struct with missing data
|
|
model.SaveAction = $scope.SaveChangesDialog.SaveAction;
|
|
model.NewName = $scope.SaveChangesDialog.ScenarioName;
|
|
model.ScenarioType = $scope.SaveChangesDialog.ScenarioType;
|
|
model.SetActive = $scope.SaveChangesDialog.SetActive;
|
|
model.CalendarDisplayMode = $scope.Filter.EntityType;
|
|
model.FilterEntityId = $scope.Filter.EntityId;
|
|
model.WorkFlowActions = $scope.WorkFlowActions;
|
|
|
|
blockUI();
|
|
try {
|
|
activityCalendarService.saveChanges(model)
|
|
.then(function () {
|
|
$scope.CalendarDataChanged = false;
|
|
|
|
$scope.$broadcast('ac.hide-save-dialog', function () {
|
|
unblockUI();
|
|
$scope.rebuildCalendar(true);
|
|
});
|
|
})
|
|
.then(null, function () {
|
|
$scope.$broadcast('ac.hide-save-dialog', function () {
|
|
unblockUI();
|
|
showErrorModal(null, null, '000008');
|
|
});
|
|
});
|
|
}
|
|
catch (e) {
|
|
console.error(e);
|
|
unblockUI();
|
|
showErrorModal(null, null, '000007');
|
|
}
|
|
|
|
return true;
|
|
};
|
|
$scope.saveScenarioForm_ScenarioTypeChanged = function () {
|
|
for (var i = 0; i < $scope.SaveChangesDialog.ChangedProjects.length; i++) {
|
|
fillSaveProjectUIModel($scope.SaveChangesDialog.ChangedProjects[i]);
|
|
}
|
|
validateSaveProjects();
|
|
}
|
|
$scope.saveScenarioForm_SaveActionChanged = function () {
|
|
$scope.saveScenarioForm_ScenarioTypeChanged();
|
|
};
|
|
$scope.saveScenarioForm_UpdateProjectionsChanged = function (projectIndex) {
|
|
var project = $scope.SaveChangesDialog.ChangedProjects[projectIndex];
|
|
if (project) {
|
|
fillSaveProjectUIModel(project);
|
|
}
|
|
validateSaveProjects();
|
|
};
|
|
// fills UI properties of project row in save changes window
|
|
function fillSaveProjectUIModel(prjItem) {
|
|
if (!prjItem)
|
|
return;
|
|
var isBottomUp = prjItem.IsBottomUp;
|
|
if ($scope.SaveChangesDialog.SaveAction == 1) {
|
|
if ($scope.SaveChangesDialog.ScenarioType == '1') // BU
|
|
isBottomUp = true;
|
|
else if ($scope.SaveChangesDialog.ScenarioType == '2') // TD
|
|
isBottomUp = false;
|
|
// else if scenario type is keep current then get isBottomUp from switcher
|
|
}
|
|
// setup UI properties
|
|
prjItem.Disabled = isBottomUp;
|
|
prjItem.Required = !prjItem.Disabled && prjItem.IsOverallocated;
|
|
prjItem.Invalid = prjItem.Required && !prjItem.UpdateProjections;
|
|
if (isBottomUp)
|
|
prjItem.UpdateProjections = true; // if user choose to save all scenarios as BU then check and disable project item
|
|
}
|
|
// sets whether to display validation message that projections should be recalculated or not
|
|
function validateSaveProjects() {
|
|
var isInvalid = false;
|
|
for (var i = 0; i < $scope.SaveChangesDialog.ChangedProjects.length; i++) {
|
|
if ($scope.SaveChangesDialog.ChangedProjects[i].Invalid) {
|
|
isInvalid = true;
|
|
break;
|
|
}
|
|
}
|
|
$scope.SaveChangesDialog.ShowValidationSummary = isInvalid;
|
|
};
|
|
function updatePagePreferenceEntityIdAsync() {
|
|
updatePagePreferenceValueAsync($scope.DisplayMode.PageKey, $scope.DisplayMode.DataSection, 'filteredCompany', $scope.Filter.EntityId);
|
|
};
|
|
function updateClientSideFilterOptions(data) {
|
|
if (!data)
|
|
return;
|
|
|
|
if (data.CostCenters) {
|
|
// Set options to Cost Centers filter
|
|
$scope.AvailableFilterOptions.CostCenters = angular.copy(data.CostCenters);
|
|
var newSelection = getSelect2NewSelection($scope.Filter.CostCenters, $scope.AvailableFilterOptions.CostCenters, 'Value');
|
|
$scope.Filter.CostCenters = newSelection;
|
|
}
|
|
|
|
if (data.ProjectRoles) {
|
|
// Set options to Project Roles filter
|
|
$scope.AvailableFilterOptions.ProjectRoles = angular.copy(data.ProjectRoles);
|
|
setProjectRolesVisibility();
|
|
}
|
|
};
|
|
function getSelect2NewSelection(controlSelection, controlOptions, valuePropertyName) {
|
|
var result = null;
|
|
|
|
if (controlSelection && angular.isArray(controlSelection)) {
|
|
var newSelection = [];
|
|
|
|
if (controlOptions && angular.isArray(controlOptions)) {
|
|
var selectedItemsCount = controlSelection.length;
|
|
var optionsCount = controlOptions.length;
|
|
|
|
for (var sIndex = 0; sIndex < selectedItemsCount; sIndex++) {
|
|
var itemToCheck = controlSelection[sIndex];
|
|
var found = false;
|
|
|
|
for (var pIndex = 0; pIndex < optionsCount; pIndex++) {
|
|
if (controlOptions[pIndex][valuePropertyName] == itemToCheck) {
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (found) {
|
|
newSelection.push(itemToCheck);
|
|
}
|
|
}
|
|
}
|
|
|
|
result = newSelection;
|
|
}
|
|
|
|
return result;
|
|
};
|
|
function setProjectRolesVisibility() {
|
|
if (!$scope.AvailableFilterOptions || !$scope.Filter || !$scope.AvailableFilterOptions.ProjectRoles)
|
|
return;
|
|
|
|
if (!angular.isArray($scope.AvailableFilterOptions.ProjectRoles))
|
|
// No project roles available for selection
|
|
return;
|
|
|
|
// Fill control with related to selected cost centers options
|
|
var expCatsCount = $scope.AvailableFilterOptions.ProjectRoles.length;
|
|
var anyCostCenterSelected = $scope.Filter.CostCenters && angular.isArray($scope.Filter.CostCenters) && ($scope.Filter.CostCenters.length > 0);
|
|
$scope.AvailableFilterOptions.ProjectRolesVisible = [];
|
|
|
|
for (var eIndex = 0; eIndex < expCatsCount; eIndex++) {
|
|
var expCat = $scope.AvailableFilterOptions.ProjectRoles[eIndex];
|
|
|
|
if (expCat && expCat.Value && expCat.CostCenterId) {
|
|
if (!anyCostCenterSelected || ($scope.Filter.CostCenters.indexOf(expCat.CostCenterId) >= 0)) {
|
|
$scope.AvailableFilterOptions.ProjectRolesVisible.push(expCat);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Fix current control selection
|
|
var newSelectedExpCats = getSelect2NewSelection($scope.Filter.ProjectRoles, $scope.AvailableFilterOptions.ProjectRolesVisible, 'Value');
|
|
$scope.Filter.ProjectRoles = newSelectedExpCats;
|
|
}
|
|
}]); |