Exemplo n.º 1
0
        /// <summary>
        /// Updates the relation.
        /// </summary>
        public async Task UpdateAsync(RelationEditorVM vm, ClaimsPrincipal principal, Guid?revertedId = null)
        {
            await ValidateRequestAsync(vm, isNew : false);

            var rel = await _db.Relations
                      .GetAsync(x => x.Id == vm.Id &&
                                x.IsComplementary == false &&
                                (x.IsDeleted == false || revertedId != null),
                                "Связь не найдена");

            var compRel = await FindComplementaryRelationAsync(rel, revertedId != null);

            var user = await GetUserAsync(principal);

            var prevVm    = rel.IsDeleted ? null : _mapper.Map <RelationEditorVM>(rel);
            var changeset = GetChangeset(prevVm, vm, rel.Id, user, revertedId);

            _db.Changes.Add(changeset);

            _mapper.Map(vm, rel);
            MapComplementaryRelation(rel, compRel);

            if (revertedId != null)
            {
                rel.IsDeleted = false;
            }

            await _validator.ValidateAsync(new[] { rel, compRel });

            _cache.Clear();
        }
Exemplo n.º 2
0
        /// <summary>
        /// Creates a new relation.
        /// </summary>
        public async Task CreateAsync(RelationEditorVM vm, ClaimsPrincipal principal)
        {
            await ValidateRequestAsync(vm, isNew : true);

            var rels       = new List <Relation>();
            var changesets = new List <Changeset>();
            var groupId    = vm.SourceIds.Length > 1 ? Guid.NewGuid() : (Guid?)null;

            var user = await GetUserAsync(principal);

            foreach (var srcId in vm.SourceIds)
            {
                var rel = _mapper.Map <Relation>(vm);
                rel.Id       = Guid.NewGuid();
                rel.SourceId = srcId;

                var compRel = new Relation {
                    Id = Guid.NewGuid()
                };
                MapComplementaryRelation(rel, compRel);

                rels.Add(rel);
                rels.Add(compRel);

                changesets.Add(GetChangeset(null, _mapper.Map <RelationEditorVM>(rel), rel.Id, user, null, groupId));
            }

            await _validator.ValidateAsync(rels);

            _db.Changes.AddRange(changesets);
            _db.Relations.AddRange(rels);

            _cache.Clear();
        }
Exemplo n.º 3
0
        /// <summary>
        /// Creates a new relation.
        /// </summary>
        public async Task CreateAsync(RelationEditorVM vm, ClaimsPrincipal principal)
        {
            await ValidateRequestAsync(vm, isNew : true);

            var newRels     = new List <Relation>();
            var updatedRels = new List <Relation>();
            var groupId     = vm.SourceIds.Length > 1 ? Guid.NewGuid() : (Guid?)null;

            var removedRelations = await _db.Relations
                                   .Where(x => vm.SourceIds.Contains(x.SourceId) &&
                                          x.DestinationId == vm.DestinationId &&
                                          x.Type == vm.Type &&
                                          x.Id != vm.Id &&
                                          x.IsDeleted == true)
                                   .ToDictionaryAsync(x => x.SourceId, x => x);

            var user = await GetUserAsync(principal);

            foreach (var srcId in vm.SourceIds)
            {
                Relation rel;

                if (removedRelations.TryGetValue(srcId, out rel))
                {
                    rel.IsDeleted = false;

                    updatedRels.Add(rel);
                }
                else
                {
                    rel          = _mapper.Map <Relation>(vm);
                    rel.Id       = Guid.NewGuid();
                    rel.SourceId = srcId;

                    newRels.Add(rel);
                }

                var compRel = new Relation {
                    Id = Guid.NewGuid()
                };
                MapComplementaryRelation(rel, compRel);
                newRels.Add(compRel);

                _db.Changes.Add(GetChangeset(null, _mapper.Map <RelationEditorVM>(rel), rel.Id, user, null, groupId));
            }

            await _validator.ValidateAsync(newRels.Concat(updatedRels).ToList());

            _db.Relations.AddRange(newRels);

            _cache.Clear();
        }
Exemplo n.º 4
0
        /// <summary>
        /// Displays the editor.
        /// </summary>
        private async Task <ActionResult> ViewEditorFormAsync(RelationEditorVM vm)
        {
            if (vm.SourceIds == null)
            {
                vm.SourceIds = Array.Empty <Guid>();
            }

            var pageIds = new[] { vm.DestinationId, vm.EventId }.Concat(vm.SourceIds.Cast <Guid?>()).ToList();
            var pageLookup = await _pages.FindPagesByIdsAsync(pageIds);

            ViewBag.Data = new RelationEditorDataVM
            {
                IsNew           = vm.Id == Guid.Empty,
                SourceItems     = GetPageLookup(vm.SourceIds),
                DestinationItem = GetPageLookup(vm.DestinationId ?? Guid.Empty),
                EventItem       = GetPageLookup(vm.EventId ?? Guid.Empty),

                Properties    = _rels.GetPropertiesForRelationType(vm.Type),
                RelationTypes = EnumHelper.GetEnumValues <RelationType>()
                                .Select(x => new SelectListItem
                {
                    Value    = x.ToString(),
                    Text     = x.GetEnumDescription(),
                    Selected = x == vm.Type
                })
            };

            return(View("Editor", vm));

            IReadOnlyList <SelectListItem> GetPageLookup(params Guid[] ids)
            {
                var result = new List <SelectListItem>();

                foreach (var id in ids)
                {
                    if (pageLookup.TryGetValue(id, out var page))
                    {
                        result.Add(new SelectListItem {
                            Selected = true, Text = page.Title, Value = page.Id.ToString()
                        });
                    }
                }

                return(result);
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Gets the changeset for updates.
        /// </summary>
        private Changeset GetChangeset(RelationEditorVM prev, RelationEditorVM next, Guid id, AppUser user, Guid?revertedId, Guid?groupId = null)
        {
            if (prev == null && next == null)
            {
                throw new ArgumentNullException();
            }

            return(new Changeset
            {
                Id = Guid.NewGuid(),
                RevertedChangesetId = revertedId,
                GroupId = groupId,
                Type = ChangesetEntityType.Relation,
                Date = DateTime.Now,
                EditedRelationId = id,
                Author = user,
                OriginalState = prev == null ? null : JsonConvert.SerializeObject(prev),
                UpdatedState = next == null ? null : JsonConvert.SerializeObject(next),
            });
        }
Exemplo n.º 6
0
        public async Task <ActionResult> Create(RelationEditorVM vm)
        {
            if (!ModelState.IsValid)
            {
                return(await ViewEditorFormAsync(vm));
            }

            try
            {
                await _rels.CreateAsync(vm, User);

                await _db.SaveChangesAsync();

                return(RedirectToSuccess("Связь создана"));
            }
            catch (ValidationException ex)
            {
                SetModelState(ex);
                return(await ViewEditorFormAsync(vm));
            }
        }
Exemplo n.º 7
0
        public async Task <ActionResult> Update(RelationEditorVM vm)
        {
            if (!ModelState.IsValid)
            {
                return(await ViewEditorFormAsync(vm));
            }

            try
            {
                await _rels.UpdateAsync(vm, User);

                await _db.SaveChangesAsync();

                _alarm.FireTreeLayoutRegenerationRequired();

                return(RedirectToSuccess("Связь обновлена"));
            }
            catch (ValidationException ex)
            {
                SetModelState(ex);
                return(await ViewEditorFormAsync(vm));
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Checks if the create/update request contains valid data.
        /// </summary>
        private async Task ValidateRequestAsync(RelationEditorVM vm, bool isNew)
        {
            var val = new Validator();

            vm.SourceIds = vm.SourceIds ?? new Guid[0];

            var pageIds = vm.SourceIds
                          .Concat(new [] { vm.DestinationId ?? Guid.Empty, vm.EventId ?? Guid.Empty })
                          .ToList();

            var pages = await _db.Pages
                        .Where(x => pageIds.Contains(x.Id))
                        .ToDictionaryAsync(x => x.Id, x => x.Type);

            var sourceTypes = vm.SourceIds.Select(x => pages.TryGetNullableValue(x)).ToList();
            var destType    = pages.TryGetNullableValue(vm.DestinationId ?? Guid.Empty);
            var eventType   = pages.TryGetNullableValue(vm.EventId ?? Guid.Empty);

            if (vm.SourceIds == null || vm.SourceIds.Length == 0)
            {
                val.Add(nameof(vm.SourceIds), "Выберите страницу");
            }
            else if (isNew == false && vm.SourceIds.Length > 1)
            {
                val.Add(nameof(vm.SourceIds), "При редактировании может быть указана только одна страница");
            }
            else if (sourceTypes.Any(x => x == null))
            {
                val.Add(nameof(vm.SourceIds), "Страница не найдена");
            }

            if (vm.DestinationId == null)
            {
                val.Add(nameof(vm.DestinationId), "Выберите страницу");
            }
            else if (destType == null)
            {
                val.Add(nameof(vm.DestinationId), "Страница не найдена");
            }

            if (destType != null && sourceTypes.Any(x => x != null && !RelationHelper.IsRelationAllowed(x.Value, destType.Value, vm.Type)))
            {
                val.Add(nameof(vm.Type), "Тип связи недопустимм для данных страниц");
            }

            if (vm.EventId != null)
            {
                if (eventType == null)
                {
                    val.Add(nameof(vm.EventId), "Страница не найдена");
                }
                else if (eventType != PageType.Event)
                {
                    val.Add(nameof(vm.EventId), "Требуется страница события");
                }
                else if (!RelationHelper.IsRelationEventReferenceAllowed(vm.Type))
                {
                    val.Add(nameof(vm.EventId), "Событие нельзя привязать к данному типу связи");
                }
            }

            if (!string.IsNullOrEmpty(vm.DurationStart) || !string.IsNullOrEmpty(vm.DurationEnd))
            {
                if (!RelationHelper.IsRelationDurationAllowed(vm.Type))
                {
                    val.Add(nameof(vm.DurationStart), "Дату нельзя указать для данного типа связи");
                }
                else
                {
                    var from = FuzzyDate.TryParse(vm.DurationStart);
                    var to   = FuzzyDate.TryParse(vm.DurationEnd);

                    if (from > to)
                    {
                        val.Add(nameof(vm.DurationStart), "Дата начала не может быть больше даты конца");
                    }
                    else if (FuzzyRange.TryParse(FuzzyRange.TryCombine(vm.DurationStart, vm.DurationEnd)) == null)
                    {
                        val.Add(nameof(vm.DurationStart), "Введите дату в корректном формате");
                    }
                }
            }

            var existingRelation = await _db.Relations
                                   .AnyAsync(x => vm.SourceIds.Contains(x.SourceId) &&
                                             x.DestinationId == vm.DestinationId &&
                                             x.Type == vm.Type &&
                                             x.Id != vm.Id);

            if (existingRelation)
            {
                val.Add(nameof(vm.DestinationId), "Такая связь уже существует!");
            }

            val.ThrowIfInvalid();
        }