コード例 #1
0
        private async Task <bool> PaymentWasCompleted(PaymentResultDTO paymentResultDTO, Order order)
        {
            if (order.BillingId == paymentResultDTO.BillingId.ToString())
            {
                return(false);
            }

            if (order.BillingId != null)
            {
                throw new Exception("Заказ с id={orderId} уже оплачен");
            }

            bool result = true;
            var  user   = _userContext.Users.First(g => g.Id == paymentResultDTO.UserId);

            if (paymentResultDTO.IsSuccessfully)
            {
                // 1. обновляем заказ
                order.BillingId   = paymentResultDTO.BillingId.ToString();
                order.PaidDateUtc = paymentResultDTO.PaymentDateUtc;
                order.Status      = OrderStatus.Processing;

                // 2. отправляем уведомление об успешной оплате
                await _mqSender.SendMessageAsync(new OrderWasPayment
                {
                    UserEmail   = user.UserName,
                    BillingId   = order.BillingId.ToString(),
                    OrderNumber = order.OrderNumber.ToString(),
                    Price       = order.TotalPrice,
                });
            }
            else
            {
                order.Status = OrderStatus.Error;
                // 1. снимаем с резервирования
                _warehouseServiceClient.AddHeader(Constants.USERID_HEADER, order.UserId.ToString());
                await _warehouseServiceClient.CancelAsync(order.OrderNumber.ToString());

                // 2. отправляем уведомление о плохой оплате
                await _mqSender.SendMessageAsync(new OrderCreatedError
                {
                    UserEmail = user.UserName,
                    Message   = $"Не удалось оплатить товар по причине {paymentResultDTO.ErrorDescription ?? string.Empty}. Заказ товара отменен. Попробуйте выполнить заказ повторно!",
                });

                result = false;
            }

            _orderContext.Update(order);
            await _orderContext.SaveChangesAsync();

            return(result);
        }
コード例 #2
0
        public async Task EventMessageSenderSendsCorrectMessageToCorrectExchangeWithCorrectTopic()
        {
            var target = new RabbitMQMessageSender(_busContext);

            await target.SendMessageAsync(_eventMessage);

            _channelMock.Verify(c => c.BasicPublish(_exchangeName, _topic, false, _propsMock.Object, _body));
        }
コード例 #3
0
        public async Task EventMessageSenderDeclaresExchange()
        {
            var target = new RabbitMQMessageSender(_busContext);

            await target.SendMessageAsync(_eventMessage);

            _channelMock.Verify(c => c.ExchangeDeclare(_exchangeName, ExchangeType.Topic,
                                                       It.IsAny <bool>(), It.IsAny <bool>(), null));
        }
コード例 #4
0
        public async Task EventMessageSenderSendsCorrectHeaderInfo()
        {
            _propsMock.SetupProperty(p => p.CorrelationId);
            _propsMock.SetupProperty(p => p.Timestamp);
            _propsMock.SetupProperty(p => p.Type);

            Guid guid      = Guid.NewGuid();
            long timestamp = DateTime.Now.Ticks;

            _eventMessage.CorrelationId = guid;
            _eventMessage.Timestamp     = timestamp;
            _eventMessage.EventType     = "String";

            var target = new RabbitMQMessageSender(_busContext);

            await target.SendMessageAsync(_eventMessage);

            Assert.AreEqual(guid.ToString(), _propsMock.Object.CorrelationId);
            Assert.AreEqual(new AmqpTimestamp(timestamp), _propsMock.Object.Timestamp);
            Assert.AreEqual("String", _propsMock.Object.Type);
        }
コード例 #5
0
        // TODO выделить минифункци reserve, код станет чище
        public async Task <ReserveProduct[]> ReserveProductsAsync(ReserveProduct[] products, string orderNumber)
        {
            var reserveProductsList = new List <ReserveProduct>();

            using (var scope = new TransactionScope(TransactionScopeOption.Required, TransactionScopeAsyncFlowOption.Enabled))
            {
                DateTime reserveDate = DateTime.UtcNow;
                foreach (var product in products)
                {
                    var remainProductCounter = await _warehouseContext.Counters.FirstOrDefaultAsync(g => g.ProductId == product.ProductId);

                    if (remainProductCounter == null)
                    {
                        reserveProductsList.Add(new ReserveProduct
                        {
                            Count       = -1,
                            OrderNumber = orderNumber,
                            ProductId   = product.ProductId,
                            ReserveDate = reserveDate,
                        });
                        continue;
                    }
                    var existReserve = await _warehouseContext.Reserves.FirstOrDefaultAsync(g => g.OrderNumber == orderNumber && g.ProductId == product.ProductId);

                    if (remainProductCounter.RemainCount < product.Count)
                    {
                        // нет достаточного количества товаров
                        reserveProductsList.Add(new ReserveProduct
                        {
                            Count       = -1,
                            OrderNumber = orderNumber,
                            ProductId   = product.ProductId,
                            ReserveDate = reserveDate,
                        });
                        continue;
                    }
                    var reserveProduct = new ReserveProduct
                    {
                        Count       = product.Count,
                        OrderNumber = orderNumber,
                        ProductId   = product.ProductId,
                        ReserveDate = reserveDate,
                    };
                    reserveProductsList.Add(reserveProduct);
                    if (existReserve != null)
                    {
                        existReserve.Count       = product.Count;
                        existReserve.ReserveDate = reserveDate;
                    }
                    else
                    {
                        _warehouseContext.Reserves.Add(reserveProduct);
                    }
                }

                // посылаем информацию о резервировании товаров
                await _mqSender.SendMessageAsync(new UpdateProductCounterByReserveRequest(orderNumber)
                {
                    Products = reserveProductsList.Where(g => g.Count > 0).Select(g => new UpdateProductCounterByReserveRequest.ReserveProduct
                    {
                        Count     = g.Count,
                        ProductId = g.ProductId
                    }).ToList()
                }, _mqOptions.Value.WarehouseRouteKey);

                await _warehouseContext.SaveChangesAsync();

                scope.Complete();
            }
            return(reserveProductsList.ToArray());
        }