private List<BillDemandDistribution> GetBillDemandDistributions (Guid instanceId, Guid initiatorId,  SightingType type, Budget2DataContext context)
 {
     if (type == SightingType.BillDemandLimitManagerSighting)
         return
             context.BillDemandDistributions.Where(
                 p => p.DemandId.HasValue &&
                 p.BillDemandId == instanceId && p.Demand.LimitId.HasValue && p.Demand.Limit.ManagerId.HasValue &&
                 p.Demand.Limit.ManagerId.Value == initiatorId).ToList();
     else if (type == SightingType.BillDemandLimitExecutorSighting)
         return
            context.BillDemandDistributions.Where(
                p => p.DemandId.HasValue &&
                p.BillDemandId == instanceId && p.Demand.LimitId.HasValue && p.Demand.Limit.ExecutorId.HasValue &&
                p.Demand.Limit.ExecutorId.Value == initiatorId).ToList();
     else
     {
         throw new ArgumentException("Неизвестный тип параллельного согласования");
     }
 }
 private List<WorkflowSighting> GetSightings (Guid instanceId, Guid initiatorId,  SightingType type, Budget2DataContext context)
 {
     return
         context.WorkflowSightings.Where(
             p => p.SighterId == initiatorId && p.EntityId == instanceId && p.SightingType ==
                  type.Id).ToList();
     
 }
        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);

            }
        }
        private void DeleteSights(Guid billDemandUid, SightingType type)
        {
            using (var scope = ReadCommittedSupressedScope)
            {
                using (var context = this.CreateContext())
                {
                    var sights =
                        context.WorkflowSightings.Where(
                            p =>
                            p.EntityId == billDemandUid &&
                            p.SightingType == type.Id);

                    context.WorkflowSightings.DeleteAllOnSubmit(sights);

                    context.SubmitChanges();
                }

                scope.Complete();
            }
        }
 private List<LimitSighting> GetCurrentSighters(Budget2DataContext context, Guid billDemandUid, SightingType sightingType)
 {
     return context.WorkflowSightings.Where(
         p =>
         p.EntityId == billDemandUid &&
         p.SightingType == sightingType.Id).Select(
             p => new LimitSighting { LimitId = p.ItemId, SighterId = p.SighterId, InitiatorId = p.InitiatorId, SightingTime = p.SightingTime })
         .Distinct().ToList();
 }
        private bool LimitSight(Guid billDemandUid, Guid sighterId, Guid initiatorId, SightingType sightingType,
                                Func<Budget2DataContext, Guid, List<LimitSighter>> sighterSelector)
        {
            bool retval = false;
            using (var scope = ReadCommittedSupressedScope)
            {
                using (var context = this.CreateContext())
                {
                    var sighters = sighterSelector(context, billDemandUid);

                    if (sighters.Count(p => p.SighterId == sighterId) == 0)
                        return false;

                    List<LimitSighter> currentSighters = GetCurrentSighters(context, billDemandUid, sightingType).ConvertAll<LimitSighter>(p => p);

                    foreach (var limitSighter in sighters.Where(p => p.SighterId == sighterId))
                    {
                        var sighter = limitSighter;
                        if (currentSighters.Count(p => p.LimitId == sighter.LimitId && p.SighterId == sighter.SighterId) == 0)
                        {
                            var newSighting = new WorkflowSighting
                            {
                                EntityId = billDemandUid,
                                Id = Guid.NewGuid(),
                                SighterId = sighterId,
                                InitiatorId = initiatorId,
                                SightingType = sightingType.Id,
                                SightingTime = DateTime.Now,
                                ItemId = sighter.LimitId
                            };
                            context.WorkflowSightings.InsertOnSubmit(newSighting);
                            currentSighters.Add(sighter);
                        }
                    }

                    retval =
                        sighters.TrueForAll(
                            p =>
                            currentSighters.FirstOrDefault(s => s.LimitId == p.LimitId && s.SighterId == p.SighterId) !=
                            null);
                    context.SubmitChanges();
                }

                scope.Complete();
            }
            return retval;
        }