public virtual async Task HandleEventAsync(EntityCreatedEto <PaymentEto> eventData)
        {
            using var currentTenant = _currentTenant.Change(eventData.Entity.TenantId);

            foreach (var item in eventData.Entity.PaymentItems.Where(item => item.ItemType == PaymentsConsts.PaymentItemType))
            {
                var orderId = Guid.Parse(item.ItemKey);

                var order = await _orderRepository.GetAsync(orderId);

                if (order.PaymentId.HasValue || order.OrderStatus != OrderStatus.Pending)
                {
                    // Todo: should cancel the payment?
                    throw new OrderIsInWrongStageException(order.Id);
                }

                if (!await _orderPaymentChecker.IsValidPaymentAsync(order, eventData.Entity, item))
                {
                    // Todo: should cancel the payment?
                    throw new OrderPaymentInvalidException(eventData.Entity.Id, orderId);
                }

                order.SetPaymentId(eventData.Entity.Id);

                await _orderRepository.UpdateAsync(order, true);
            }
        }
        public virtual async Task HandleEventAsync(EntityCreatedEto <TenantEto> eventData)
        {
            try
            {
                using (_currentTenant.Change(null))
                {
                    var tenant = await _tenantRepository.FindAsync(eventData.Entity.Id, true);

                    if (tenant == null)
                    {
                        return;
                    }
                    var connectionStrings = new ConnectionStrings();
                    foreach (var tenantConnectionString in tenant.ConnectionStrings)
                    {
                        connectionStrings[tenantConnectionString.Name] = tenantConnectionString.Value;
                    }
                    var cacheItem = new TenantConfigurationCacheItem(tenant.Id, tenant.Name, connectionStrings);

                    var cacheKey = TenantConfigurationCacheItem.CalculateCacheKey(eventData.Entity.Id.ToString());
                    await _cache.SetAsync(cacheKey, cacheItem);
                }
            }
            catch (Exception ex)
            {
                _logger.LogException(ex);
            }
        }
Example #3
0
        public virtual async Task HandleEventAsync(EntityCreatedEto <PaymentEto> eventData)
        {
            if (eventData.Entity.PaymentItems.All(item => item.ItemType != PaymentsConsts.PaymentItemType))
            {
                return;
            }

            using var changeTenant = _currentTenant.Change(eventData.Entity.TenantId);

            var payment = await _paymentRepository.FindAsync(eventData.Entity.Id);

            if (payment != null)
            {
                return;
            }

            payment = _objectMapper.Map <PaymentEto, Payment>(eventData.Entity);

            payment.SetPaymentItems(
                _objectMapper.Map <List <PaymentItemEto>, List <PaymentItem> >(eventData.Entity.PaymentItems));

            payment.PaymentItems.ForEach(FillPaymentItemStoreId);

            await _paymentRepository.InsertAsync(payment, true);

            if (payment.CompletionTime.HasValue)
            {
                await PublishPaymentCompletedEventAsync(payment);
            }

            if (payment.CanceledTime.HasValue)
            {
                await PublishPaymentCanceledEventAsync(payment);
            }
        }
        public async Task HandleEventAsync(EntityCreatedEto <TenantEto> eventData)
        {
            Logger.LogInformation($"Handled distributed event for a new tenant creation. TenantId: {eventData.Entity.Id}");

            using (_currentTenant.Change(eventData.Entity.Id, eventData.Entity.Name))
            {
                await _dataSeeder.SeedAsync(tenantId : eventData.Entity.Id);
            }
        }
Example #5
0
 protected virtual async Task PublishResultEventAsync(EntityCreatedEto <OrderEto> orderCreatedEto, bool isSuccess)
 {
     await _distributedEventBus.PublishAsync(new ProductInventoryReductionAfterOrderPlacedResultEto
     {
         TenantId  = orderCreatedEto.Entity.TenantId,
         OrderId   = orderCreatedEto.Entity.Id,
         IsSuccess = isSuccess
     });
 }
    public async Task Should_Invoke_DistributedEventHandler_With_EntityCreatedEto()
    {
        var localHandler = new MyDistributedEventHandler();
        var eventData    = new EntityCreatedEto <MyEntity>(new MyEntity());

        await _eventHandlerInvoker.InvokeAsync(localHandler, eventData, eventData.GetType());

        localHandler.MyEventDataCount.ShouldBe(0);
        localHandler.EntityCreatedCount.ShouldBe(1);
    }
        public virtual async Task HandleEventAsync(EntityCreatedEto <OrderEto> eventData)
        {
            using var changeTenant = _currentTenant.Change(eventData.Entity.TenantId);

            var models = new List <ConsumeInventoryModel>();

            foreach (var orderLine in eventData.Entity.OrderLines)
            {
                // Todo: Should use ProductHistory.
                var product = await _productRepository.FindAsync(orderLine.ProductId);

                var productSku = product?.ProductSkus.FirstOrDefault(sku => sku.Id == orderLine.ProductSkuId);

                if (productSku == null)
                {
                    await PublishInventoryReductionResultEventAsync(eventData, false);

                    return;
                }

                if (product.InventoryStrategy != InventoryStrategy.ReduceAfterPlacing)
                {
                    continue;
                }

                if (!await _productManager.IsInventorySufficientAsync(product, productSku, orderLine.Quantity))
                {
                    await PublishInventoryReductionResultEventAsync(eventData, false);

                    return;
                }

                models.Add(new ConsumeInventoryModel(
                               product, productSku, eventData.Entity.StoreId, orderLine.Quantity));
            }

            foreach (var model in models)
            {
                if (await _productManager.TryReduceInventoryAsync(
                        model.Product, model.ProductSku, model.Quantity, true))
                {
                    continue;
                }

                await TryRollbackInventoriesAsync(models);

                await _unitOfWorkManager.Current.RollbackAsync();

                await PublishInventoryReductionResultEventAsync(eventData, false, true);

                return;
            }

            await PublishInventoryReductionResultEventAsync(eventData, true);
        }
        public virtual async Task HandleEventAsync(EntityCreatedEto <OrderEto> eventData)
        {
            using var changeTenant = _currentTenant.Change(eventData.Entity.TenantId);

            await _distributedEventBus.PublishAsync(new ProductInventoryReductionAfterOrderPlacedResultEto
            {
                TenantId  = eventData.Entity.TenantId,
                OrderId   = eventData.Entity.Id,
                IsSuccess = true
            });
        }
        public virtual async Task HandleEventAsync(EntityCreatedEto <TenantEto> eventData)
        {
            var tenantDto = await _tenantAppService.GetAsync(eventData.Entity.Id);

            var tenantConnectionStringsDto = await _tenantAppService.GetConnectionStringAsync(eventData.Entity.Id);

            var connectionStrings = new ConnectionStrings();

            foreach (var tenantConnectionString in tenantConnectionStringsDto.Items)
            {
                connectionStrings[tenantConnectionString.Name] = tenantConnectionString.Value;
            }
            var cacheItem = new TenantConfigurationCacheItem(tenantDto.Id, tenantDto.Name, connectionStrings);

            var cacheKey = TenantConfigurationCacheItem.CalculateCacheKey(eventData.Entity.Id.ToString());
            await _cache.SetAsync(cacheKey, cacheItem);
        }
Example #10
0
        public virtual async Task HandleEventAsync(EntityCreatedEto <RefundEto> eventData)
        {
            using var uow = _unitOfWorkManager.Begin(isTransactional: true);

            using var changeTenant = _currentTenant.Change(eventData.Entity.TenantId);

            var refund = await _refundRepository.FindAsync(eventData.Entity.Id);

            if (refund != null)
            {
                return;
            }

            var payment = await _paymentRepository.FindAsync(eventData.Entity.PaymentId);

            if (payment == null)
            {
                return;
            }

            refund = _objectMapper.Map <RefundEto, Refund>(eventData.Entity);

            refund.SetRefundItems(
                _objectMapper.Map <List <RefundItemEto>, List <RefundItem> >(eventData.Entity.RefundItems));

            refund.RefundItems.ForEach(item =>
            {
                FillRefundItemStoreId(item);
                FillRefundItemOrderId(item);
            });

            FillRefundItemOrderLines(refund);

            await _refundRepository.InsertAsync(refund, true);

            if (refund.CompletedTime.HasValue)
            {
                uow.OnCompleted(async() => await _distributedEventBus.PublishAsync(new EShopRefundCompletedEto
                {
                    Refund = _objectMapper.Map <Refund, EShopRefundEto>(refund)
                }));
            }

            await uow.CompleteAsync();
        }
Example #11
0
        public virtual async Task HandleEventAsync(EntityCreatedEto <OrderEto> eventData)
        {
            using (_currentTenant.Change(eventData.Entity.TenantId))
            {
                var models = new List <ReduceInventoryModel>();

                foreach (var orderLine in eventData.Entity.OrderLines)
                {
                    var product = await _productRepository.FindAsync(orderLine.ProductId);

                    var productSku = product?.ProductSkus.FirstOrDefault(sku => sku.Id == orderLine.ProductSkuId);

                    if (productSku == null || product.InventoryStrategy != InventoryStrategy.ReduceAfterPlacing)
                    {
                        continue;
                    }

                    if (!await _productManager.IsInventorySufficientAsync(product, productSku, eventData.Entity.StoreId,
                                                                          orderLine.Quantity))
                    {
                        await _distributedEventBus.PublishAsync(new ProductInventoryReductionAfterOrderPlacedResultEto
                                                                { TenantId = eventData.Entity.TenantId, OrderId = eventData.Entity.Id, IsSuccess = false });

                        return;
                    }

                    models.Add(new ReduceInventoryModel
                    {
                        Product    = product,
                        ProductSku = productSku,
                        StoreId    = eventData.Entity.StoreId,
                        Quantity   = orderLine.Quantity
                    });
                }

                foreach (var model in models)
                {
                    await _productManager.TryReduceInventoryAsync(model.Product, model.ProductSku, model.StoreId,
                                                                  model.Quantity);
                }

                await _distributedEventBus.PublishAsync(new ProductInventoryReductionAfterOrderPlacedResultEto
                                                        { TenantId = eventData.Entity.TenantId, OrderId = eventData.Entity.Id, IsSuccess = true });
            }
        }
        public virtual async Task HandleEventAsync(EntityCreatedEto <OrderEto> eventData)
        {
            if (!eventData.Entity.PaymentExpiration.HasValue)
            {
                return;
            }

            var args = new UnpaidOrderAutoCancelArgs
            {
                TenantId = eventData.Entity.TenantId,
                OrderId  = eventData.Entity.Id
            };

            await _backgroundJobManager.EnqueueAsync(
                args : args,
                delay : eventData.Entity.PaymentExpiration.Value.Subtract(_clock.Now) // Todo: use a absolute time.
                );
        }
Example #13
0
        public virtual async Task HandleEventAsync(EntityCreatedEto <PaymentEto> eventData)
        {
            using var currentTenant = _currentTenant.Change(eventData.Entity.TenantId);

            foreach (var item in eventData.Entity.PaymentItems.Where(item => item.ItemType == PaymentsConsts.PaymentItemType))
            {
                var order = await _orderRepository.FindAsync(item.ItemKey);

                if (order == null || order.PaymentId.HasValue ||
                    !await _orderPaymentChecker.IsValidPaymentAsync(order, eventData.Entity, item))
                {
                    throw new OrderPaymentInvalidException(eventData.Entity.Id, item.ItemKey);
                }

                order.SetPaymentId(eventData.Entity.Id);

                await _orderRepository.UpdateAsync(order, true);
            }
        }
Example #14
0
        public virtual async Task HandleEventAsync(EntityCreatedEto <PaymentEto> eventData)
        {
            var payment = eventData.Entity;

            var items = payment.PaymentItems.Where(item => item.ItemType == PrepaymentConsts.TopUpPaymentItemType)
                        .ToList();

            foreach (var item in items)
            {
                var accountId = Guid.Parse(item.ItemKey);

                using var currentTenant = _currentTenant.Change(payment.TenantId);

                var account = await _accountRepository.GetAsync(accountId);

                account.SetPendingTopUpPaymentId(payment.Id);

                await _accountRepository.UpdateAsync(account, true);
            }
        }
        public virtual async Task HandleEventAsync(EntityCreatedEto <OrderEto> eventData)
        {
            if (!Guid.TryParse(eventData.Entity.GetProperty <string>(CouponsConsts.OrderCouponIdPropertyName),
                               out var couponId))
            {
                return;
            }

            var discountAmount = eventData.Entity.GetProperty <decimal>(CouponsConsts.OrderCouponDiscountAmountPropertyName);

            var coupon = await _couponRepository.GetAsync(couponId);

            if (coupon.OrderId != eventData.Entity.Id)
            {
                throw new InvalidCouponOrderIdException(eventData.Entity.Id, coupon.OrderId);
            }

            coupon.SetUsed(_clock.Now, discountAmount, eventData.Entity.Currency);

            await _couponRepository.UpdateAsync(coupon, true);
        }
Example #16
0
        public virtual async Task HandleEventAsync(EntityCreatedEto <TodoItemEto> eventData)
        {
            var dateTime    = eventData.Entity.CreationTime;
            var todoSummary = await _todoSummaryRepository.FindAsync(
                x => x.Year == dateTime.Year &&
                x.Month == dateTime.Month &&
                x.Day == dateTime.Day
                );

            if (todoSummary == null)
            {
                todoSummary = await _todoSummaryRepository.InsertAsync(new TodoSummary(dateTime));
            }
            else
            {
                todoSummary.Increase();
                await _todoSummaryRepository.UpdateAsync(todoSummary);
            }

            Console.WriteLine("Increased total count: " + todoSummary);
        }
Example #17
0
        public virtual async Task HandleEventAsync(EntityCreatedEto <TenantEto> eventData)
        {
            // 禁用租户过滤器
            using (_dataFilter.Disable <IMultiTenant>())
            {
                var tenant = await _tenantRepository.FindAsync(eventData.Entity.Id, true);

                if (tenant == null)
                {
                    return;
                }
                var connectionStrings = new ConnectionStrings();
                foreach (var tenantConnectionString in tenant.ConnectionStrings)
                {
                    connectionStrings[tenantConnectionString.Name] = tenantConnectionString.Value;
                }
                var cacheItem = new TenantConfigurationCacheItem(tenant.Id, tenant.Name, connectionStrings);

                var cacheKey = TenantConfigurationCacheItem.CalculateCacheKey(eventData.Entity.Id.ToString());
                await _cache.SetAsync(cacheKey, cacheItem);
            }
        }
 public Task HandleEventAsync(EntityCreatedEto <MySimpleEventData> eventData)
 {
     TenantId = _currentTenant.Id;
     return(Task.CompletedTask);
 }
Example #19
0
 public Task HandleEventAsync(EntityCreatedEto <SampleEto> eventData)
 {
     _logger.LogInformation($"TEST ENTITY CREATED EVENT RECEIVED => Message: {eventData.Entity.Message}");
     return(Task.CompletedTask);
 }
Example #20
0
 public Task HandleEventAsync(EntityCreatedEto <MyEntity> eventData)
 {
     EntityCreatedCount++;
     return(Task.CompletedTask);
 }
        /// <summary>
        /// 接收添加用户事件,发布本地事件
        /// </summary>
        /// <param name="eventData"></param>
        /// <returns></returns>
        public async Task HandleEventAsync(EntityCreatedEto <UserEto> eventData)
        {
            var localUserCreateEventData = new EntityCreatedEventData <UserEto>(eventData.Entity);

            await _localEventBus.PublishAsync(localUserCreateEventData);
        }