public bool IsCurrentUserAllowedToExecuteCommandInCurrentState(ServiceIdentity identity, WorkflowState state, Guid instanceId)
        {
            if (state == null)
            {
                return ValidateInitiator(identity, instanceId);
            }

            if (state.Type != WorkflowType.DemandAdjustmentWorkflow)
                return false;

            if (state == WorkflowState.DemandAdjustmentDraft)
                return ValidateInitiator(identity, instanceId);

            if (state == WorkflowState.DemandAdjustmentSourceDemandLimitManagerSighting)
                return ValidateSourceDemandLimitManager(identity, instanceId);

            if (state == WorkflowState.DemandAdjustmentSourceDemandLimitExecutorSighting)
                return ValidateSourceDemandLimitExecutor(identity, instanceId);

            if (state == WorkflowState.DemandAdjustmentTargetDemandLimitExecutorSighting)
                return ValidateTargetDemandLimitExecutor(identity, instanceId);

            if (state == WorkflowState.DemandAdjustmentTargetDemandLimitManagerSighting)
                return ValidateTargetDemandLimitManager(identity, instanceId);

            if (state == WorkflowState.DemandAdjustmentUPKZCuratorSighting)
                return AuthorizationService.IsInRole(identity.Id, BudgetRole.Curator);

            if (state == WorkflowState.DemandAdjustmentUPKZHeadSighting)
                return AuthorizationService.IsInRole(identity.Id, BudgetRole.UPKZHead);

            return false;
        }
        public List<WorkflowCommandType> AddAdditionalCommand(ServiceIdentity getCurrentIdentity, IEnumerable<ServiceIdentity> identities, WorkflowState currentState, Guid instanceUid, List<WorkflowCommandType> allowedOperations)
        {
            if (currentState == WorkflowState.DemandDraft || currentState == WorkflowState.DemandAgreed || currentState == WorkflowState.DemandRollbackRequested || currentState == null)
                return allowedOperations;

            if (ValidateInitiatorForRollback(getCurrentIdentity, instanceUid))
                allowedOperations.Add(WorkflowCommandType.Rollback);
            else if (!getCurrentIdentity.IsImpersonated)
            {
                var identity = identities.FirstOrDefault(i => ValidateInitiatorForRollback(i, instanceUid));
                    if (identity != null)
                    {
                        getCurrentIdentity.TryImpersonate(identity.Id);
                        allowedOperations.Add(WorkflowCommandType.Rollback);
                    }

            }

            return allowedOperations;
        }
        private bool ValidateInitiatorHead(ServiceIdentity identity, Guid instanceId)
        {
            var billDemand = BillDemandBuinessService.GetBillDemand(instanceId);

                 if (!billDemand.AuthorId.HasValue)
                     return false;
                 var heads = SecurityEntityService.GetHeadIds(billDemand.AuthorId.Value, billDemand.BudgetId);

            return heads.Contains(identity.Id);
        }
        private bool ValidateTargetDemandLimitManager(ServiceIdentity identity, Guid instanceId)
        {

            using (var scope = new TransactionScope(TransactionScopeOption.Suppress))
            {
                using (var context = CreateContext())
                {
                   return context.DemandAdjustments.Count(
                        p =>
                        p.Id == instanceId && p.TargetDemandId.HasValue &&
                        p.TargetDemand.LimitId.HasValue && p.TargetDemand.Limit.ManagerId == identity.Id) == 1;
                }
            }
        }
 private bool ValidateInitiator(ServiceIdentity identity, Guid instanceId)
 {
     using (var scope = new TransactionScope(TransactionScopeOption.Suppress))
     {
         using (var context = CreateContext())
         {
             return context.DemandAdjustments.Count(p => p.Id == instanceId && p.CreatorId == identity.Id) == 1;
         }
     }
 }
        private bool ValidateCurrentUserInAgreementOP(ServiceIdentity identity, Guid instanceId)
        {
            using (var scope = new TransactionScope(TransactionScopeOption.Suppress))
            {
                using (var context = CreateContext())
                {
                    var demand = context.Demands.FirstOrDefault(
                        p =>
                        p.Id == instanceId && p.AgreementCfo.HasValue);

                    if (demand == null)
                        return false;

                    Guid? identityDivisionId = GetIdentityDivisionId(context, identity, demand.BudgetVersion.BudgetId);

                    if (!identityDivisionId.HasValue)
                        return false;

                    return demand.AgreementCfo == identityDivisionId.Value;

                }
            }
        }
 public List<WorkflowCommandType> AddAdditionalCommand(ServiceIdentity getCurrentIdentity, IEnumerable<ServiceIdentity> identities, WorkflowState currentState, Guid instanceUid, List<WorkflowCommandType> allowedOperations)
 {
     return allowedOperations;
 }
 private bool ValidateLimitExecutor(ServiceIdentity identity, Guid instanceId)
 {
     return CheckLimitSighting(identity, instanceId, SightingType.BillDemandLimitExecutorSighting);
 }
 public void RaiseDenial(Guid instanceId, ServiceIdentity serviceIdentity, string comment)
 {
     WorkflowSupportService.UpgradeWorkflow(Runtime, instanceId);
     var args = new DenialCommandEventArgs(instanceId, serviceIdentity.Id, serviceIdentity.ImpersonatedId) { Comment = comment };
     Denial(null, args);
 }
 public void RaiseSighting(Guid instanceId, ServiceIdentity serviceIdentity)
 {
     WorkflowSupportService.UpgradeWorkflow(Runtime, instanceId);
     Sighting(null, new WorkflowEventArgsWithInitiator(instanceId, serviceIdentity.Id, serviceIdentity.ImpersonatedId));
 }
        public bool IsCurrentUserAllowedToExecuteCommandInCurrentState(ServiceIdentity identity, WorkflowState state, Guid instanceId)
        {
            if (state == null)
            {
                return ValidateInitiator(identity, instanceId);
            }

            if (state.Type != WorkflowType.DemandWorkflow)
                return false;

            if (state == WorkflowState.DemandDraft)
                return ValidateInitiator(identity, instanceId);

            if (state == WorkflowState.DemandUPKZCuratorSighting)
                return AuthorizationService.IsInRole(identity.Id, BudgetRole.Curator);

            if (state == WorkflowState.DemandRollbackRequested)
                return AuthorizationService.IsInRole(identity.Id, BudgetRole.Curator);

            if (state == WorkflowState.DemandUPKZHeadSighting)
                return AuthorizationService.IsInRole(identity.Id, BudgetRole.UPKZHead);

            if (state == WorkflowState.DemandOPExpertSighting)
                return AuthorizationService.IsInRole(identity.Id, BudgetRole.Expert) && ValidateCurrentUserInOP(identity, instanceId);

            if (state == WorkflowState.DemandOPHeadSighting)
                return AuthorizationService.IsInRole(identity.Id, BudgetRole.DivisionHead) && ValidateCurrentUserInOP(identity, instanceId);

            if (state == WorkflowState.DemandAgreementOPExpertSighting)
            {
                //http://pmtask.ru/redmine/issues/867
                //return AuthorizationService.IsInRole(identity.Id, BudgetRole.Expert) && ValidateCurrentUserInAgreementOP(identity, instanceId);
                return ValidateCurrentUserInAgreementOP(identity, instanceId);
            }

            //if (state == WorkflowState.DemandAgreementOPHeadSighting)
            //    return AuthorizationService.IsInRole(identity.Id, BudgetRole.DivisionHead) && ValidateCurrentUserInAgreementOP(identity, instanceId);

            if (state == WorkflowState.DemandInitiatorHeadSighting /*|| state == WorkflowState.DemandAgreementInitiatorHeadSighting*/)
               return  ValidateInitiatorHead(identity, instanceId);



            return false;
        }
        private bool ValidateInitiatorForRollback(ServiceIdentity identity, Guid instanceId)
        {
            using (var context = CreateContext())
            {
                var demand = context.Demands.SingleOrDefault(p => p.Id == instanceId && p.PlanningTypeId != 2);
                if (demand == null)
                    return false;

                return demand.AuthorId == identity.Id;
            }
        }
 private Guid? GetIdentityDivisionId(Budget2DataContext context, ServiceIdentity identity, Guid budgetId)
 {
     var employee =
         context.Employees.FirstOrDefault(p => p.SecurityTrusteeId == identity.Id && p.BudgetId == budgetId);
     return employee == null ? null : employee.StructDivisionId;
 }
        private bool ValidateLimitManager(ServiceIdentity identity, Guid instanceId)
        {
            var bd = BillDemandBuinessService.GetBillDemand(instanceId);
            if (bd.BudgetPartId == 0)
                return CheckLimitSighting(identity, instanceId, SightingType.BillDemandLimitManagerSighting);
            else
            {
               var sighters =  BillDemandBuinessService.GetLimitManagerSighters(instanceId, true);
               var sightings = BillDemandBuinessService.GetLimitManagerSightings(instanceId);
               foreach (var sighter in sighters)
               {
                   if (sightings.Count(s=>s.LimitId == sighter.LimitId) < 1)
                   {
                       if (SecurityEntityService.GetHeadIdsByDivision(sighter.LimitId, bd.BudgetId).Contains(identity.Id))
                           return true;
                   }
               }

                return false;
            }
        }
 public void RaiseRollback(Guid instanceId, ServiceIdentity serviceIdentity, string comment)
 {
     WorkflowSupportService.UpgradeWorkflow(Runtime,instanceId);
     Rollback(null, new DenialCommandEventArgs(instanceId, serviceIdentity.Id, serviceIdentity.ImpersonatedId) { Comment = comment });
 }
        private bool CheckLimitSighting(ServiceIdentity identity, Guid instanceId, SightingType type)
        {
            var dlo = new DataLoadOptions();
            dlo.LoadWith<BillDemandDistribution>(p => p.Demand);
            dlo.LoadWith<Demand>(p => p.Limit);

            using (var context = CreateContext())
            {
                context.LoadOptions = dlo;

                var distributions = GetBillDemandDistributions(instanceId, identity.Id, type, context);

                if (distributions.Count() == 0)
                    return false;

                var sightings = GetSightings(instanceId, identity.Id, type, context);

                if (sightings.Count() == 0)
                    return true;

                return !distributions.TrueForAll(
                   p =>
                   p.DemandId.HasValue && p.Demand.LimitId.HasValue &&
                   sightings.FirstOrDefault(s => s.ItemId == p.Demand.LimitId)!=null);

            }
        }
 public void RaiseExport(Guid instanceId, ServiceIdentity serviceIdentity)
 {
     BillDemandWorkflowService.RaiseExport(new WorkflowEventArgsWithInitiator(instanceId, serviceIdentity.Id, serviceIdentity.ImpersonatedId));
 }
        private bool ValidateInitiator(ServiceIdentity identity, Guid instanceId)
        {
            using (var context = CreateContext())
            {
                var billDemand = context.BillDemands.SingleOrDefault(p => p.Id == instanceId);
                if (billDemand == null)
                    return false;

                if (billDemand.AuthorId == identity.Id)
                    return true;
            }

            return false;
        }
        public void SetWorkflowState(Guid instanceId, ServiceIdentity serviceIdentity, string stateName, string comment)
        {
            var workflowState = WorkflowStateService.GetWorkflowState(instanceId);


            if (workflowState.WorkflowStateName != stateName || workflowState.IsInitial)
            //Для черновиков устанавливаем всегда это временно
            {
                WorkflowSupportService.TryUpgradeWorkflow(Runtime, instanceId);

                WorkflowParcelService.AddParcel(instanceId,
                                                new WorkflowSetStateParcel()
                                                {
                                                    Comment = comment,
                                                    InitiatorId = serviceIdentity.Id,
                                                    Command = WorkflowCommand.Unknown,
                                                    PreviousWorkflowState = workflowState
                                                });
                bool isIdled = true;
                using (var sync = new WorkflowSync(Runtime, instanceId))
                {
                    if (!WorkflowSupportService.CreateWorkflowIfNotExists(Runtime, instanceId, workflowState.Type))
                    //Это ожидание создания воркфлоу
                    {
                        sync.WaitHandle.WaitOne(600000);
                        isIdled = sync.WasIdled;
                    }

                }
                //Если воркфлоу не стало идленым - то его необходимо удалить полностью и создать заново
                if (!isIdled)
                {
                    using (var context = this.CreateContext())
                    {
                        context.DeleteWorkflowInPesistenceStore(instanceId);
                        context.SubmitChanges();
                    }
                    using (var sync = new WorkflowSync(Runtime, instanceId))
                    {
                        if (!WorkflowSupportService.CreateWorkflowIfNotExists(Runtime, instanceId, workflowState.Type))
                        //Это ожидание создания воркфлоу
                        {
                            sync.WaitHandle.WaitOne(600000);
                        }

                    }
                }

                var instance = new StateMachineWorkflowInstance(Runtime, instanceId);
                var newWorkflowState = WorkflowStateService.GetWorkflowState(instanceId);
                if (newWorkflowState.WorkflowStateName != stateName)
                {
                    using (var sync = new WorkflowSync(Runtime, instanceId))
                    //Это ожидание завершения установки состояния воркфлоу
                    {
                        instance.SetState(stateName);
                        sync.WaitHandle.WaitOne(600000);
                    }
                }
                WorkflowState state =
                    WorkflowState.AllStates.First(
                        ws => ws.WorkflowStateName == stateName && ws.Type.Id == workflowState.Type.Id);
                if (!state.IsFinal && !state.IsInitial)
                    WorkflowSupportService.RewriteWorkflow(instanceId, state);
                //Для РД удаляем историю согласования
                if (workflowState.Type == WorkflowType.BillDemandWorkfow)
                {
                    if (state == WorkflowState.BillLimitManagerSighting)
                    {
                        BillDemandBuinessService.LimitExecutorResetSights(instanceId);
                    }

                    BillDemandBuinessService.LimitExecutorResetSights(instanceId);
                    BillDemandBuinessService.LimitManagerResetSights(instanceId);
                }

            }
        }
        public bool IsCurrentUserAllowedToExecuteCommandInCurrentState(ServiceIdentity identity, WorkflowState state,
                                                                    Guid instanceId)
        {
            if (state == null)
            {
                return ValidateInitiator(identity, instanceId);
            }

            if (state.Type != WorkflowType.BillDemandWorkfow)
                return false;

            if (state == WorkflowState.BillDemandOnPayment)
                return true;

            if ((state == WorkflowState.BillDemandDraft) || (state == WorkflowState.BillDemandPostingAccounting) || state == WorkflowState.BillDemandDraftForTechnicalDenial || state == WorkflowState.BillDemandInitiatorConfirmation)
                return ValidateInitiator(identity, instanceId);

            if (state == WorkflowState.BillDemandUPKZCntrollerSighting)
                return AuthorizationService.IsInRole(identity.Id, BudgetRole.Controller);

            if (state == WorkflowState.BillDemandUPKZCuratorSighting)
                return AuthorizationService.IsInRole(identity.Id, BudgetRole.Curator);

            if (state == WorkflowState.BillDemandUPKZHeadSighting)
                return AuthorizationService.IsInRole(identity.Id, BudgetRole.UPKZHead);

            if (state == WorkflowState.BillLimitManagerSighting)
                return ValidateLimitManager(identity, instanceId);

            if (state == WorkflowState.BillDemandInAccountingWithExport)
                return  AuthorizationService.IsInRole(identity.Id, BudgetRole.Accountant);

            if (state == WorkflowState.BillDemandLimitExecutorSighting)
                return ValidateLimitExecutor(identity, instanceId);

            if (state == WorkflowState.BillDemandHeadInitiatorSighting)
                return ValidateInitiatorHead(identity, instanceId);

            return false;
        }
        private bool ValidateInitiatorHead(ServiceIdentity identity, Guid instanceId)
        {
            using (var context = CreateContext())
            {
                var dlo = new DataLoadOptions();
                dlo.LoadWith<Demand>(d => d.BudgetVersion);
                context.LoadOptions = dlo;

                var demand = context.Demands.FirstOrDefault(
                    p =>
                    p.Id == instanceId && p.AuthorId.HasValue);

                if (demand == null)
                    return false;

                var heads = SecurityEntityService.GetHeadIds(demand.AuthorId.Value, demand.BudgetVersion.BudgetId);

                return heads.Contains(identity.Id);
            }
        }