示例#1
0
        /// <summary>
        /// Автоматическая выдача прав на проектные документы.
        /// </summary>
        public virtual void GrantAccessRightsToProjectDocuments()
        {
            var startDate     = Calendar.Now;
            var lastStartDate = Docflow.PublicFunctions.Module.GetLastAgentRunDate(Constants.Module.LastProjectDocumentRightsUpdateDate);

            // Измененные документы.
            Logger.DebugFormat("GrantAccessRightsToProjectDocuments: Start get changed projects documents.");
            var queue = new List <Sungero.Projects.Structures.ProjectDocumentRightsQueueItem.ProxyQueueItem>();
            var changedDocumentIds = Docflow.OfficialDocuments.GetAll(d => d.Modified >= lastStartDate && d.Modified <= startDate &&
                                                                      (d.Project != null || (Docflow.Addendums.Is(d) && d.LeadingDocument.Project != null)))
                                     .Select(d => d.Id);

            foreach (var documentId in changedDocumentIds)
            {
                var document = Docflow.OfficialDocuments.GetAll(d => d.Id == documentId).FirstOrDefault();
                if (document == null)
                {
                    continue;
                }

                var project = Docflow.PublicFunctions.OfficialDocument.GetProject(document);
                if (project == null)
                {
                    continue;
                }
                queue.AddRange(Functions.Module.CreateAccessRightsProjectDocumentQueueItemWithAddendum(document.Id, project.Id));
            }

            // Измененные проекты.
            Logger.DebugFormat("GrantAccessRightsToProjectDocuments: Start get changed projects members documents.");
            var changedProjectsQueueItems = ProjectMemberRightsQueueItems.GetAll().ToList();

            foreach (var memberQueueItem in changedProjectsQueueItems)
            {
                var project = Projects.GetAll(p => p.Id == memberQueueItem.ProjectId).FirstOrDefault();
                if (project == null)
                {
                    continue;
                }

                var allProjects = ModuleFunctions.GetProjectAndSubProjects(project).Cast <Docflow.IProjectBase>().ToList();

                var changedMembersDocuments = Docflow.OfficialDocuments.GetAll(d => allProjects.Contains(d.Project));

                foreach (var document in changedMembersDocuments)
                {
                    queue.AddRange(Functions.Module.CreateAccessRightsProjectDocumentQueueItemWithAddendum(document.Id, project.Id));
                }
            }

            var table = ProjectDocumentRightsQueueItems.Info.DBTableName;
            var ids   = Sungero.Domain.IdentifierGenerator.GenerateIdentifiers(table, queue.Count).ToList();

            for (int i = 0; i < queue.Count; i++)
            {
                queue[i].Id = ids[i];
            }
            Docflow.PublicFunctions.Module.WriteStructuresToTable(table, queue);
            Logger.DebugFormat("GrantAccessRightsToProjectDocuments: Added to queue {0} documents.", queue.Count);

            if (changedProjectsQueueItems.Any())
            {
                Docflow.PublicFunctions.Module.FastDeleteQueueItems(changedProjectsQueueItems.Select(q => q.Id).ToList());
            }

            // Обновить дату запуска агента в базе.
            Docflow.PublicFunctions.Module.UpdateLastAgentRunDate(Constants.Module.LastProjectDocumentRightsUpdateDate, startDate);

            // Выдать права на документы.
            var step    = 5;
            var error   = 0;
            var isEmpty = false;

            for (int i = 0; i < 10000; i = i + step)
            {
                // Если элементов больше нет - заканчиваем.
                if (isEmpty)
                {
                    break;
                }

                var result = Transactions.Execute(
                    () =>
                {
                    Logger.DebugFormat("GrantAccessRightsToProjectDocuments: Start process queue from {0}.", i);

                    // Т.к. в конце транзакции элементы удаляются, в Take берем просто N новых элементов.
                    var queueItemPart = ProjectDocumentRightsQueueItems.GetAll().Skip(error).Take(step).ToList();
                    if (!queueItemPart.Any())
                    {
                        // Завершаем транзакцию, если больше нечего обрабатывать.
                        isEmpty = true;
                        return;
                    }

                    var accessRightsGranted = queueItemPart
                                              .Where(q => Functions.Module.AddDocumentToFolder(q) && Functions.Module.GrantRightsToProjectDocuments(q))
                                              .ToList();
                    if (accessRightsGranted.Any())
                    {
                        Docflow.PublicFunctions.Module.FastDeleteQueueItems(accessRightsGranted.Select(a => a.Id).ToList());
                    }
                    error += queueItemPart.Count - accessRightsGranted.Count;
                });
                if (!result)
                {
                    error += step;
                }
            }
        }
示例#2
0
        public override void Saving(Sungero.Domain.SavingEventArgs e)
        {
            base.Saving(e);

            #region  абота с папками

            // Создание папки проекта.
            if (_obj.Folder == null)
            {
                var folder = Folders.Create();
                folder.Name = _obj.ShortName;

                folder.Items.Add(_obj);
                _obj.Folder = folder;
            }

            // Вложение папки проекта в корневую папку или папку ведущего проекта.
            var projectsFolder = Folders.GetAll().Single(f => f.Uid == Constants.Module.ProjectFolders.ProjectFolderUid);

            if (_obj.State.Properties.LeadingProject.IsChanged)
            {
                // Удаление из папки предыдущего проекта.
                var leading = _obj.State.Properties.LeadingProject.OriginalValue;
                if (leading != null && !Equals(leading, _obj.LeadingProject) && leading.Folder != null && leading.Folder.Items.Contains(_obj.Folder))
                {
                    leading.Folder.Items.Remove(_obj.Folder);
                }
            }

            if (_obj.LeadingProject == null)
            {
                if (projectsFolder != null && !projectsFolder.Items.Contains(_obj.Folder) && _obj.Stage != Stage.Completed)
                {
                    projectsFolder.Items.Add(_obj.Folder);
                }
            }
            else
            {
                // Удаление из корневой папки.
                if (projectsFolder != null)
                {
                    projectsFolder.Items.Remove(_obj.Folder);
                }

                // Добавление в папку ведущего проекта.
                if (_obj.LeadingProject.Folder != null && !_obj.LeadingProject.Folder.Items.Contains(_obj.Folder))
                {
                    _obj.LeadingProject.Folder.Items.Add(_obj.Folder);
                }
            }

            #endregion

            #region Переименование групп, папок

            if (_obj.State.Properties.ShortName.IsChanged)
            {
                _obj.Folder.Name = _obj.ShortName;
            }

            #endregion

            #region Перенос в папку Архив и обратно

            if (_obj.State.Properties.Stage.OriginalValue != _obj.Stage && _obj.LeadingProject == null)
            {
                var rootProjectFolder = Folders.GetAll().Single(f => f.Uid == Constants.Module.ProjectFolders.ProjectFolderUid);
                var archiveFolder     = Folders.GetAll().Single(f => f.Uid == Constants.Module.ProjectFolders.ProjectArhiveFolderUid);
                var projectFolder     = _obj.Folder;

                if (_obj.Stage == Stage.Completed)
                {
                    archiveFolder.Items.Add(projectFolder);
                    rootProjectFolder.Items.Remove(projectFolder);
                }
                else
                {
                    rootProjectFolder.Items.Add(projectFolder);
                    archiveFolder.Items.Remove(projectFolder);
                }
            }

            #endregion

            #region Создание и обновление папок проекта

            Functions.Project.UpdateClassifier(_obj);

            #endregion

            #region Очередь выдачи прав участнику

            var properties     = _obj.State.Properties;
            var needAddToQueue = false;
            if (properties.Manager.IsChanged && properties.Manager.OriginalValue != _obj.Manager)
            {
                needAddToQueue = true;
            }

            if (properties.Administrator.IsChanged && _obj.Administrator != null && properties.Administrator.OriginalValue != _obj.Administrator)
            {
                needAddToQueue = true;
            }

            if (properties.InternalCustomer.IsChanged && _obj.InternalCustomer != null && properties.InternalCustomer.OriginalValue != _obj.InternalCustomer)
            {
                needAddToQueue = true;
            }

            if (properties.TeamMembers.IsChanged && _obj.TeamMembers.Any())
            {
                needAddToQueue = true;
            }

            if (_obj.State.Properties.LeadingProject.IsChanged)
            {
                var originalLeadProject = properties.LeadingProject.OriginalValue;
                var leadProject         = _obj.LeadingProject;
                if (leadProject != null && leadProject != originalLeadProject)
                {
                    needAddToQueue = true;
                }
            }

            if (needAddToQueue)
            {
                Logger.DebugFormat("CreateProjectMemberRightsQueueItem: project {0}", _obj.Id);
                var queueItem = ProjectMemberRightsQueueItems.Create();
                queueItem.ProjectId = _obj.Id;
                queueItem.Save();

                // Добавить признак того, что нужно запустить ФП Автоматическое назначение прав на документы.
                e.Params.Add(Docflow.PublicConstants.OfficialDocument.GrantAccessRightsToProjectDocument, true);
            }

            #endregion

            #region Выдача прав РП и администратору

            var recipients = new List <IRecipient>()
            {
                _obj.Manager
            };
            if (_obj.Administrator != null)
            {
                recipients.Add(_obj.Administrator);
            }

            var folders = new List <IFolder>();
            if (_obj.Folder != null)
            {
                folders.Add(_obj.Folder);
            }
            folders.AddRange(_obj.Classifier.Where(c => c.Folder != null).Select(f => f.Folder).ToList());

            foreach (var recipient in recipients)
            {
                foreach (var folder in folders)
                {
                    if (!folder.AccessRights.IsGrantedDirectly(DefaultAccessRightsTypes.FullAccess, recipient) && (Locks.GetLockInfo(folder) == null || !Locks.GetLockInfo(folder).IsLockedByOther))
                    {
                        folder.AccessRights.Grant(recipient, DefaultAccessRightsTypes.FullAccess);
                    }
                }

                if (!_obj.AccessRights.IsGrantedDirectly(DefaultAccessRightsTypes.FullAccess, recipient) && Equals(recipient, _obj.Manager))
                {
                    _obj.AccessRights.Grant(recipient, DefaultAccessRightsTypes.FullAccess);
                }

                if (!Functions.Module.CheckGrantedRights(_obj, recipient, DefaultAccessRightsTypes.Change) && Equals(recipient, _obj.Administrator))
                {
                    _obj.AccessRights.Grant(recipient, DefaultAccessRightsTypes.Change);
                }
            }

            #endregion
        }