Beispiel #1
0
        private async ValueTask <(bool isSuccess, string error)> FullUpdate(CategoryDTO categoryDTO, Category oldCategory)
        {
            // В случае когда нам не удаётся обновить данную модель
            // Мы должны удалить те фото, которые были добавлены
            var scheduleAddedPhotoList = new List <Photo>();

            // Если обновление прошло успешно
            // То нужно окончательно удалить ненужные фото
            var scheduleDeletePhotoList = new List <Photo>();

            using var transaction = await _context.Database.BeginTransactionAsync();

            (bool isSuccess, string error) cancelUpdate((bool isSuccess, string error) result)
            {
                transaction.Rollback();
                return(result);
            }

            try
            {
                #region Create new entity and migrate/update photo list

                var(newCategory, error) = await this.CreateEntity(categoryDTO,
                                                                  addEntityDbFunc : _repository.AddCategory,
                                                                  defaultPhotoList : oldCategory.Photos,
                                                                  scheduleAddedPhotoList : scheduleAddedPhotoList,
                                                                  scheduleDeletePhotoList : scheduleDeletePhotoList);

                if (newCategory is null)
                {
                    return(cancelUpdate((false, error)));
                }

                var newCategoryId = newCategory.CategoryId;
                newCategory = null;

                #endregion

                // Для старой Entry (категории) загружаем из базы коллекцию (лист) подкатегорий
                await _context
                .Entry(oldCategory)
                .Collection(x => x.Subcategories)
                .LoadAsync();

                // Поскольку по окончанию цикла мы сохраняем изменения в БД
                // Список подкатегорий уменьшается, поэтому используется цикл while
                while (oldCategory.Subcategories.Count != 0)
                {
                    var oldSubcategory = oldCategory.Subcategories.ElementAt(0);
                    var newSubcategory = default(Subcategory);

                    // Загружаем для подкатегории фотографии
                    await _repository.LoadPhotoCollection(oldSubcategory);

                    // Создаём новую подкатегорию
                    newSubcategory = new Subcategory()
                    {
                        CategoryId    = newCategoryId,
                        SubcategoryId = oldSubcategory.SubcategoryId,

                        SeoTitle       = oldSubcategory.SeoTitle,
                        SeoDescription = oldSubcategory.SeoDescription,
                        SeoKeywords    = oldSubcategory.SeoKeywords,

                        Description = oldCategory.Description,

                        Alias    = oldSubcategory.Alias,
                        Products = new List <Product>(),
                        Photos   = new List <Photo>(),
                    };

                    // Удаляем фотографию для старой
                    _photoEntityUpdater.MovePhotosToEntity(newSubcategory, oldSubcategory.Photos);

                    // Загружаем список продуктов
                    await _context
                    .Entry(oldSubcategory)
                    .Collection(x => x.Products)
                    .LoadAsync();

                    foreach (var product in oldSubcategory.Products)
                    {
                        await _repository.LoadPhotoCollection(product);

                        var newProduct = new Product()
                        {
                            CategoryId    = newSubcategory.CategoryId,
                            SubcategoryId = newSubcategory.SubcategoryId,
                            ProductId     = product.ProductId,

                            Alias       = product.Alias,
                            Price       = product.Price,
                            Description = product.Description,

                            SeoTitle       = product.SeoTitle,
                            SeoDescription = product.SeoDescription,
                            SeoKeywords    = product.SeoKeywords,

                            Photos = new List <Photo>()
                        };

                        _photoEntityUpdater.MovePhotosToEntity(newProduct, product.Photos);

                        newSubcategory.Products.Add(newProduct);
                    }

                    // Добавляем новую подкатегорию
                    _context.Add(newSubcategory);

                    // Теперь мы можем изменить заказы, т.к. новая категория с подкатегорией и продуктами добавлены
                    var categoryKeys = oldSubcategory
                                       .Products
                                       .Select(x => x.CategoryId);

                    var subcategoryKeys = oldSubcategory
                                          .Products
                                          .Select(x => x.SubcategoryId);

                    var productKeys = oldSubcategory
                                      .Products
                                      .Select(x => x.ProductId);

                    var orderList = _context.OrderPosition
                                    .Where(
                        order => categoryKeys.Contains(order.Product.CategoryId) &&
                        subcategoryKeys.Contains(order.Product.SubcategoryId) &&
                        productKeys.Contains(order.Product.ProductId)
                        )
                                    .ToList();

                    // Обновляем ссылку на продукт
                    orderList.ForEach(order =>
                    {
                        var newProduct = newSubcategory.Products.First(product => oldSubcategory.CategoryId == order.Product.CategoryId &&
                                                                       product.SubcategoryId == order.Product.SubcategoryId &&
                                                                       product.ProductId == order.Product.ProductId);

                        order.Product = newProduct;

                        _context.Update(order);
                    });

                    // Теперь старая подкатегория не нужно
                    _context.Remove(oldSubcategory);

                    // Сохраняем изменения
                    await _repository.SaveChangesAsync();
                }

                // Если всё прошло удачно, удаляем старую категорию
                await _repository.DeleteCategory(oldCategory.CategoryId);

                transaction.Commit();

                foreach (var photo in scheduleDeletePhotoList)
                {
                    await _photoSaver.RemoveFileFromRepository(photo, updateDB : false);
                }

                return(true, null);
            }
            catch (Exception ex)
            {
                foreach (var photo in scheduleAddedPhotoList)
                {
                    await _photoSaver.RemoveFileFromRepository(photo, updateDB : false);
                }

                var errMsg = "Ошибка при обновлении категории. Возможно подкатегория и товар с такой категорией уже существует.";

                _logger.LogError(ex, errMsg);

                return(cancelUpdate((
                                        false,
                                        $"{errMsg} Текст ошибки: {ex.Message}"
                                        )));
            }
        }
Beispiel #2
0
        /// <inheritdoc/>
        public async Task <ServiceExecuteResult <int> > AddOrder(OrderCreateDTO orderDTO)
        {
            using var transaction = await _context.Database.BeginTransactionAsync();

            var orderId = -1;

            try
            {
                /// Создаём рыбу модели заказа
                var order = new Order()
                {
                    OrderId    = 0,
                    FIO        = orderDTO.FIO,
                    Phone      = orderDTO.Phone,
                    Email      = orderDTO.Email,
                    Date       = DateTime.Now,
                    StatusId   = (int)OrderStatusEnum.New,
                    TotalPrice = 0
                };

                var client = new Client()
                {
                    Email = orderDTO.Email,
                    FIO   = orderDTO.FIO,
                    Phone = orderDTO.Phone,
                    IsIncludeInMailing = true
                };

                await _repository.AddOrder(order);

                await _repository.AddClient(client);

                /// Прокидываем связь в позиции заказа
                /// с настоящим товаром
                order.OrderPositions = orderDTO.OrderPositions.Select(x =>
                                                                      new OrderPosition()
                {
                    OrderPositionId = 0,

                    Number = x.Number,
                    Price  = 0,
                    Name   = "",

                    OrderId = order.OrderId,

                    CategoryId    = x.Product.CategoryId,
                    SubcategoryId = x.Product.SubcategoryId,
                    ProductId     = x.Product.ProductId
                })
                                       .ToList();

                await _repository.UpdateOrder(order);

                /// Подгружаем товары, которые мы связали на прошлом шагу
                await _context.Entry(order)
                .Collection(x => x.OrderPositions)
                .Query()
                .Include(x => x.Product)
                .LoadAsync();

                foreach (var orderPos in order.OrderPositions)
                {
                    orderPos.Price = orderPos.Product.Price;
                    orderPos.Name  = orderPos.Product.Alias;
                }
                order.TotalPrice = order.OrderPositions.Select(x => x.Number * x.Price).Sum();

                await _repository.UpdateOrder(order);

                orderId = order.OrderId;

                transaction.Commit();
            }
            catch (Exception ex)
            {
                transaction.Rollback();

                var msg = $"Не удалось создать заказ по след. причине: {ex.Message}";
                _logger.LogError(ex, $"{msg}. Модель запроса:\n{JsonHelper.Serialize(orderDTO)}");

                return(new ServiceExecuteResult <int>
                {
                    IsSuccess = false,
                    Error = msg,
                    Result = 0
                });
            }

            try
            {
                if (orderId <= 0)
                {
                    throw new Exception($"Отсутствует номер заказа.");
                }

                await _emailService.SendOrderInformation(orderId);
            }
            catch (Exception ex)
            {
                var msg = $"Не удалось отправить письмо на почту по след. причине: {ex.Message}";
                _logger.LogError(ex, msg);

                return(new ServiceExecuteResult <int>
                {
                    IsSuccess = false,
                    Error = msg,
                    Result = orderId != -1 ? orderId : 0
                });
            }

            return(new ServiceExecuteResult <int>
            {
                IsSuccess = true,
                Result = orderId,
            });
        }
 /// <inheritdoc/>
 public async Task LoadPhotoCollection <T>(T model) where T : IPhoto
 {
     await Context.Entry(model)
     .Collection("Photos")
     .LoadAsync();
 }
Beispiel #4
0
        public async ValueTask <(bool isSuccess, string error)> FullUpdateSubcategory(SubcategoryDTO subcategoryDTO, Subcategory oldSubcategory)
        {
            // В случае когда нам не удаётся обновить данную модель
            // Мы должны удалить те фото, которые были добавлены
            var scheduleAddedPhotoList = new List <Photo>();

            // Если обновление прошло успешно
            // То нужно окончательно удалить ненужные фото
            var scheduleDeletePhotoList = new List <Photo>();

            using var transaction = await _context.Database.BeginTransactionAsync();

            (bool isSuccess, string error) cancelUpdate((bool isSuccess, string error) result)
            {
                transaction.Rollback();
                return(result);
            }

            try
            {
                #region Create new entity and migrate/update photo list

                var(newSubcategory, error) = await CreateSubcategory(subcategoryDTO,
                                                                     defaultPhotoList : oldSubcategory.Photos,
                                                                     scheduleAddedPhotoList : scheduleAddedPhotoList,
                                                                     scheduleDeletePhotoList : scheduleDeletePhotoList);

                if (newSubcategory is null)
                {
                    return(cancelUpdate((false, error)));
                }

                #endregion

                // Загружаем список продуктов
                await _context
                .Entry(oldSubcategory)
                .Collection(x => x.Products)
                .LoadAsync();

                foreach (var product in oldSubcategory.Products)
                {
                    await _context
                    .Entry(product)
                    .Collection(x => x.Photos)
                    .LoadAsync();

                    var newProduct = new Product()
                    {
                        CategoryId    = newSubcategory.CategoryId,
                        SubcategoryId = newSubcategory.SubcategoryId,
                        ProductId     = product.ProductId,

                        Alias       = product.Alias,
                        Price       = product.Price,
                        Description = product.Description,

                        SeoTitle       = product.SeoTitle,
                        SeoDescription = product.SeoDescription,
                        SeoKeywords    = product.SeoKeywords,

                        Photos = new List <Photo>()
                    };

                    _photoEntityUpdater.MovePhotosToEntity(newProduct, product.Photos);

                    newSubcategory.Products.Add(newProduct);
                }

                // Теперь мы можем изменить заказы, т.к. новая подкатегория и продукты добавлены
                var categoryKeys = oldSubcategory
                                   .Products
                                   .Select(x => x.CategoryId);

                var subcategoryKeys = oldSubcategory
                                      .Products
                                      .Select(x => x.SubcategoryId);

                var productKeys = oldSubcategory
                                  .Products
                                  .Select(x => x.ProductId);

                var orderList = _context.OrderPosition
                                .Where(
                    order => categoryKeys.Contains(order.Product.CategoryId) &&
                    subcategoryKeys.Contains(order.Product.SubcategoryId) &&
                    productKeys.Contains(order.Product.ProductId)
                    )
                                .ToList();

                // Обновляем ссылку на продукт
                orderList.ForEach(order =>
                {
                    var newProduct = newSubcategory.Products.First(product => oldSubcategory.CategoryId == order.Product.CategoryId &&
                                                                   product.SubcategoryId == order.Product.SubcategoryId &&
                                                                   product.ProductId == order.Product.ProductId);

                    order.Product = newProduct;

                    _context.Update(order);
                });

                // Теперь старая подкатегория не нужна
                _context.Remove(oldSubcategory);

                // Сохраняем изменения
                await _context.SaveChangesAsync();

                transaction.Commit();

                foreach (var photo in scheduleDeletePhotoList)
                {
                    await _photoSaver.RemoveFileFromRepository(photo, updateDB : false);
                }

                return(true, null);
            }
            catch (Exception ex)
            {
                foreach (var photo in scheduleAddedPhotoList)
                {
                    await _photoSaver.RemoveFileFromRepository(photo, updateDB : false);
                }

                var errMsg = "Ошибка при обновлении подкатегории. Возможно товар с такой подкатегорией уже существует.";

                _logger.LogError(ex, errMsg);

                return(cancelUpdate((
                                        false,
                                        $"{errMsg} Текст ошибки: {ex.Message}"
                                        )));
            }
        }