public void CreateReservation(Reservation src)
        {
            if (src.IsNull())
            {
                throw new ArgumentNullException(nameof(src));
            }
            if (src.TotalPrice.CheckDecimalValue().Not())
            {
                throw new ArgumentException(nameof(src.TotalPrice));
            }
            if (src.Quantity <= 0)
            {
                throw new ArgumentException(nameof(src.Quantity));
            }
            if (src.ProductId.IsEmpty())
            {
                throw new ArgumentException(nameof(src.ProductId));
            }

            var product = new ProductService()
                          .GetById(new EntityGetByIdReq
            {
                Id = src.ProductId
            });

            if (product.IsNull())
            {
                throw new InvalidOperationException("Товар не найден.");
            }

            var item = new EntReservation
            {
                Id = src.Id.IsNotEmpty()
                    ? src.Id
                    : Guid.NewGuid(),
                Characteristics = src.Characteristics,
                TotalPrice      = src.Quantity * product.Price,
                Quantity        = src.Quantity
            };

            Db.Reservations.Add(item);

            Db.SaveChanges();
        }
 private Reservation Map(EntReservation src)
 {
     return(Mapper.Map <EntReservation, Reservation>(src));
 }
        public void Reserve(ReserveReq req)
        {
            if (req.IsNull())
            {
                throw new ArgumentNullException(nameof(req));
            }
            if (req.ProductId.IsEmpty())
            {
                throw new ArgumentException(nameof(req.ProductId));
            }
            if (req.Quantity <= 0)
            {
                throw new ArgumentException(nameof(req.Quantity));
            }

            try
            {
                TransactionOptions transOpt = new TransactionOptions
                {
                    IsolationLevel = IsolationLevel.Serializable
                };

                using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew, transOpt))
                {
                    using (var context = new StorageDatabaseContextFactory().Create())
                    {
                        string sqlQuery = $"SELECT * FROM [ExpressShop.Storage].[dbo].[EntProducts] WITH (UPDLOCK) WHERE Id = '{req.ProductId}'";

                        var product = context.Products
                                      .SqlQuery(sqlQuery)
                                      .FirstOrDefault();

                        Logger.Write($"{Thread.CurrentThread.Name}. Получение товара из бд. Текущий остаток: {product.TotalQuantity}");
                        Logger.Write($"{Thread.CurrentThread.Name}. Запрос товара. Количество: {req.Quantity}");

                        if (product.TotalQuantity == 0)
                        {
                            Logger.Write($"{Thread.CurrentThread.Name}. Товар закончился");

                            scope.Complete();
                            return;
                        }
                        else if (product.TotalQuantity - req.Quantity < 0)
                        {
                            Logger.Write($"{Thread.CurrentThread.Name}. Количество товара, запрошенное для бронирования, больше чем есть на складе");

                            scope.Complete();
                            return;
                        }
                        else
                        {
                            product.TotalQuantity -= req.Quantity;

                            var reservation = new EntReservation
                            {
                                Id = Guid.NewGuid(),
                                Characteristics = product.Characteristics,
                                ProductId       = product.Id,
                                Quantity        = req.Quantity,
                                OwnerId         = Guid.NewGuid()
                            };

                            context.Reservations.Add(reservation);

                            context.SaveChanges();

                            Logger.Write($"{Thread.CurrentThread.Name}. Создание бронирования");
                            Logger.Write($"{Thread.CurrentThread.Name}. Сохранение товара. Остаток: {product.TotalQuantity}");
                        }
                    }

                    scope.Complete();
                }
            }
            catch (Exception ex)
            {
                Logger.Write($"{Thread.CurrentThread.Name}. Произошла ошибка при бронировании товара: {ex.Message}");
            }
        }