'use strict'; app.controller('supplyDemandReportController', ['$scope', '$timeout', '$q', '$filter', 'activityCalendarService', 'activityCalendarUIService', 'dataSources', function ($scope, $timeout, $q, $filter, activityCalendarService, activityCalendarUIService, dataSources) { $scope.UpdateFilterOptionsUrl = '/SupplyDemandReport/GetFilterOptions'; $scope.GroupByMode = { SupplyDemandReport: '5', }; $scope.SortByMode = { Name: 'Name', Type: 'Type', Date: 'Date', Priority: 'Priority' }; var defaultGroupByItems = [ { value: $scope.GroupByMode.SupplyDemandReport, text: 'Supply and Demand' }, ]; $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.SupplyDemandReport] = '/Content/templates/SupplyDemandReport/_supplyDemandCalendar.html?v=' + new Date().getTime(); $scope.FilterIsValid = false; $scope.FilterOptions = {}; $scope.AvailableFilterOptions = {}; $scope.DisplayMode = { IsViewModeMonth: true, IsUOMHours: false, ShowAvgTotals: false, GroupByItems: defaultGroupByItems, GroupBy: { Value: defaultGroupByItems[0].value, // Hardcoded AC view mode: Group By Projects Hide: false, Disabled: false }, CapacityMode: { Value: '4', // Remaining/Capacity 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[3].value, // Hardcoded sorting - by Priority SortOrder: true, // ascending IsAvgMode: function () { return !this.IsUOMHours && this.ShowAvgTotals; }, BackUrlTitle: null }; $scope.Filter = { ProjectStatuses: { Value: null, Disabled: false }, Clients: { Value: null, Disabled: false }, Projects: { Value: null, Disabled: false }, Teams: { Value: null, Disabled: false }, StartDate: null, EndDate: null, ShowFilters: true, EntityType: activityCalendarUIService.filterEntityType.report, // Left for compatibility with data & UI services EntityId: 'SupplyDemand' // Left for compatibility with data & UI services }; // 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; $scope.DisplayMode = angular.extend({}, $scope.DisplayMode, ctrlOptions.DisplayMode); // $scope.Filter = angular.extend({}, $scope.Filter, ctrlOptions.Filter); var filterOptionsTasks = []; filterOptionsTasks.push(dataSources.loadProjectStatuses()); if (filterOptionsTasks && angular.isArray(filterOptionsTasks)) { var preferencesTask = loadUserPagePreferencesAsync(ctrlOptions.DisplayMode.DataSection, $scope.DisplayMode.PageKey); filterOptionsTasks.push(preferencesTask); $q.all(filterOptionsTasks) .then(function (asyncResults) { initPermanentFilterOptions(asyncResults[0]); $scope.DisplayMode.ShowAvgTotals = Object.parseBoolean(getDataSectionOptions(_USR_PREF_AVG_KEY)); $scope.changeGroupBy(); unblockUI(); }) .then(null, function () { unblockUI(); showErrorModal(null, null, '000005'); }); } } catch (e) { console.error(e); unblockUI(); showErrorModal(null, null, '000006'); } }; // ui methods $scope.ngIncludeLoaded = function () { $scope.rebuildCalendar(); }; $scope.rebuildCalendar = function (forceDataReload) { if (!$scope.FilterIsValid) return; var filterForRequest = castUiFilterToRequestFilter($scope.Filter); $timeout(function () { // broadcast event in next digest to let angular to reload template if necessary in current digest $scope.$broadcast('ac.rebuild-calendar', filterForRequest, $scope.DisplayMode, forceDataReload); }); }; $scope.onOptionsChanged = function (key, value) { if (!$scope.FilterIsValid) return; blockUI(); $timeout(function () { $scope.$broadcast('ac.options-changed', $scope.DisplayMode, key, value); unblockUI(); }, 200); }; $scope.changeCapacityMode = function () { $scope.$broadcast('totalsAsChanged', $scope.DisplayMode.CapacityMode.Value); }; $scope.changeGroupBy = function () { $scope.DisplayMode.CalendarView = $scope.Templates[$scope.DisplayMode.GroupBy.Value]; }; $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); }; $scope.SelectedFilterStatusesChanged = function () { var updateGuide = { updateClients: true, updateProjects: true, updateTeams: true, } updateFilterOptions(updateGuide) validateFilter(); }; $scope.SelectedFilterClientsChanged = function () { var updateGuide = { updateProjects: true, updateTeams: true, } updateFilterOptions(updateGuide) validateFilter(); }; $scope.SelectedFilterProjectsChanged = function () { var updateGuide = { updateProjects: false, updateTeams: true, } updateFilterOptions(updateGuide) validateFilter(); }; function updateFilterOptions(info) { if (info) { if (info.updateClients) { $scope.Filter.Clients.Disabled = true; } if (info.updateProjects) { $scope.Filter.Projects.Disabled = true; } if (info.updateTeams) { $scope.Filter.Teams.Disabled = true; } } var model = { Statuses: angular.copy($scope.Filter.ProjectStatuses.Value), Clients: angular.copy($scope.Filter.Clients.Value), Projects: angular.copy($scope.Filter.Projects.Value) }; var promise = activityCalendarService.loadACFilterOptionsAsync($scope.UpdateFilterOptionsUrl, model, true); promise.then(function (data) { setFilterOptions(data, info); setFilterControlsState(false); }, function (response) { setFilterControlsState(false); throw 'An error occurred while loading dictionary with project statuses /Status/LoadStatuses'; }); } function setFilterControlsState(disable) { $scope.Filter.Clients.Disabled = (disable === true); $scope.Filter.Projects.Disabled = (disable === true); $scope.Filter.Teams.Disabled = (disable === true); validateFilter(); } function initPermanentFilterOptions(projectStatuses) { var statusesSorted = projectStatuses ? $filter('sortObjectsBy')(projectStatuses, 'Name', false) : []; $scope.FilterOptions.ProjectStatuses = statusesSorted; validateFilter(); } function setFilterOptions(data, controlsToUpdate) { if (!data) return; var clients = data && angular.isArray(data.Projects) ? $filter('orderBy')(data.Clients, 'Text', false) : []; var projects = data && angular.isArray(data.Projects) ? $filter('orderBy') (data.Projects, 'Text', false): []; var teams = data && angular.isArray(data.Teams) ? $filter('orderBy')(data.Teams, 'Text', false) : []; if (!controlsToUpdate || controlsToUpdate.updateClients) { $scope.FilterOptions.Clients = clients; var newSelection = getSelect2NewSelection($scope.Filter.Clients.Value, $scope.FilterOptions.Clients, 'Value'); $scope.Filter.Clients.Value = newSelection; } if (!controlsToUpdate || controlsToUpdate.updateProjects) { $scope.FilterOptions.Projects = projects; var newSelection = getSelect2NewSelection($scope.Filter.Projects.Value, $scope.FilterOptions.Projects, 'Value'); $scope.Filter.Projects.Value = newSelection; } if (!controlsToUpdate || controlsToUpdate.updateTeams) { $scope.FilterOptions.Teams = teams; var newSelection = getSelect2NewSelection($scope.Filter.Teams.Value, $scope.FilterOptions.Teams, 'Value'); $scope.Filter.Teams.Value = newSelection; } }; 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 castUiFilterToRequestFilter(filter) { if (!filter) return; var result = { Statuses: filter.ProjectStatuses && angular.isArray(filter.ProjectStatuses.Value) ? angular.copy(filter.ProjectStatuses.Value) : [], Clients: filter.Clients && angular.isArray(filter.Clients.Value) ? angular.copy(filter.Clients.Value) : [], Projects: filter.Projects && angular.isArray(filter.Projects.Value) ? angular.copy(filter.Projects.Value) : [], Teams: filter.Teams && angular.isArray(filter.Teams.Value) ? angular.copy(filter.Teams.Value) : [], StartDate: filter.StartDate ? angular.copy(filter.StartDate) : null, EndDate: filter.EndDate ? angular.copy(filter.EndDate) : null, EntityType: filter.EntityType, // left for compatibility with calendar services EntityId: filter.EntityId // left for compatibility with calendar services } return result; }; function validateFilter() { $scope.FilterIsValid = !$scope.Filter.Projects.Disabled && !$scope.Filter.Teams.Disabled && $scope.Filter.ProjectStatuses && angular.isArray($scope.Filter.ProjectStatuses.Value) && $scope.Filter.ProjectStatuses.Value.length && (!$scope.Filter.StartDate || !$scope.Filter.EndDate || (new Date($scope.Filter.EndDate) > new Date($scope.Filter.StartDate))); } }]);