Example #1
0
        public void Should_Credit_On_Order_Cancel()
        {
            //Arrange
            var domainEventDispatcher = new DomainEventDispatcher();
            var eventStore            = EventStore.Create(domainEventDispatcher);

            domainEventDispatcher.RegisterHandler <BuyOrderCreatedDomainEvent>(new BuyOrderCreatedHandler(eventStore));
            domainEventDispatcher.RegisterHandler <BuyOrderCancelledDomainEvent>(new BuyOrderCancelledHandler(eventStore));

            //Act
            var account = Account.Create(1_000);

            eventStore.Commit(account);

            var order = Order.Create(account.Id, OrderSide.Buy, "PETR4", 10, 10M);

            eventStore.Commit(order);

            order.Cancel();
            eventStore.Commit(order);

            //Assert
            var storedAccount = Account.Load(eventStore.GetById(account.Id));

            Assert.Equal(3, storedAccount.Version);
            Assert.Equal(1_000, storedAccount.Ballance);
        }
        public void ShouldDebitAccountDtoOnOrderCreation()
        {
            //Arrange
            var projectionHost        = new ProjectorHost();
            var domainEventDispatcher = new DomainEventDispatcher();

            var eventStore = EventStore.Create(projectionHost, domainEventDispatcher);
            var dtoStore   = MemoryCache.Create();

            projectionHost.Add(new AccountProjector(dtoStore));
            projectionHost.Add(new OrderProjector(dtoStore));

            domainEventDispatcher.RegisterHandler <BuyOrderCreatedDomainEvent>(new BuyOrderCreatedHandler(eventStore));
            domainEventDispatcher.RegisterHandler <BuyOrderCancelledDomainEvent>(new BuyOrderCancelledHandler(eventStore));

            //Act
            var account = Account.Create(1_000);

            eventStore.Commit(account);

            var order = Order.Create(account.Id, OrderSide.Buy, "PETR4", 10, 10M);

            eventStore.Commit(order);

            //Assert
            var orderDto = dtoStore.Get <OrderDto>(order.Id);

            Assert.Equal(order.Symbol, orderDto.Symbol);
            Assert.Equal(order.Quantity, orderDto.Quantity);
            Assert.Equal(order.Price, orderDto.Price);

            var accountDto = dtoStore.Get <AccountDto>(account.Id);

            Assert.Equal(900, accountDto.Ballance);
        }
        public void ShouldUpdateOrderDtoLeavesQuantityAfterExecution()
        {
            //Arrange
            var projectionHost = new ProjectorHost();

            var domainEventDispatcher = new DomainEventDispatcher();
            var eventStore            = EventStore.Create(projectionHost, domainEventDispatcher);
            var dtoStore = MemoryCache.Create();

            domainEventDispatcher.RegisterHandler <BuyOrderCreatedDomainEvent>(new BuyOrderCreatedHandler(eventStore));

            projectionHost.Add(new AccountProjector(dtoStore));
            projectionHost.Add(new OrderProjector(dtoStore));

            //Act
            var account = Account.Create(10_000);

            eventStore.Commit(account);

            var order = Order.Create(account.Id, OrderSide.Buy, "PETR4", 100, 10M);

            order.Execute(Trade.Create(Guid.NewGuid(), order.Id, 75));
            eventStore.Commit(order);

            //Assert
            var accountDto = dtoStore.Get <AccountDto>(account.Id);

            Assert.Equal(9_000, accountDto.Ballance);

            var orderDto = dtoStore.Get <OrderDto>(order.Id);

            Assert.Equal(order.Symbol, orderDto.Symbol);
            Assert.Equal <uint>(75, orderDto.ExecutedQuantity);
            Assert.Equal <uint>(25, orderDto.LeavesQuantity);
        }
        public void Check_DomainEvents_ActivityAdded_Raise()
        {
            //given

            //existing project
            var project = Project.From(EntityId.From(1u), Description.From("descriptionText"));

            //a activity it is attached to it
            var activity = Activity.From(Description.From("activity to do"), EntityId.From(1u),
                                         EntityId.From(1u), ActivityStatus.From(1));

            var projectOptionsBuilder = new DbContextOptionsBuilder <ProjectDbContext>();

            projectOptionsBuilder.UseSqlite("Data Source=todoagility_proj_activity_reference.db;");
            var projectDbContext = new ProjectDbContext(projectOptionsBuilder.Options);
            var repProject       = new ProjectRepository(projectDbContext);

            using var projectDbSession = new DbSession <IProjectRepository>(projectDbContext, repProject);
            repProject.Add(project);
            projectDbSession.SaveChanges();
            var handlerActivityAdded = new ActivityAddedHandler(projectDbSession);
            var dispatcher           = new DomainEventDispatcher();

            dispatcher.Subscribe(typeof(ActivityAddedEvent).FullName, handlerActivityAdded);

            //when
            dispatcher.Publish(ActivityAddedEvent.For(activity));

            //then
            var proj = repProject.Get(EntityId.From(1u));

            Assert.True(proj.Activities.Count > 0);
        }
        public void MessageHandler_ValidMessage_RegisteredHandlerCalled()
        {
            // Arrange
            MyTarget target = new MyTarget();

            var messageConsumer         = Substitute.For <IMessageConsumer>();
            var serviceProvider         = Substitute.For <IServiceProvider>();
            var logger                  = Substitute.For <ILogger <DomainEventDispatcher> >();
            var eventTypeNamingStrategy = Substitute.For <IEventTypeNamingStrategy>();

            eventTypeNamingStrategy.GetEventTypeName(typeof(MyDomainEvent)).Returns(typeof(MyDomainEvent).FullName);

            DomainEventDispatcher dispatcher = new DomainEventDispatcher(
                _subscriberId, target.domainEventHandlers(), messageConsumer, eventTypeNamingStrategy, logger);

            dispatcher.Initialize();

            // Act
            dispatcher.MessageHandler(DomainEventPublisher.MakeMessageForDomainEvent(aggregateType,
                                                                                     aggregateId, new Dictionary <string, string>()
            {
                { MessageHeaders.Id, messageId }
            },
                                                                                     new MyDomainEvent(), eventTypeNamingStrategy), serviceProvider);

            // Assert
            Assert.True(target.Queue.TryPeek(out var dee));
            Assert.NotNull(dee);
            Assert.AreEqual(aggregateId, dee.AggregateId);
            Assert.AreEqual(aggregateType, dee.AggregateType);
            Assert.AreEqual(messageId, dee.EventId);
        }
        public async Task <MarketerCommandResponse> Handle(ChangeShopMarketerCommand command)
        {
            var shop = await _shopRepository.FindAsync(command.ShopId);

            if (shop == null)
            {
                throw new DomainException("فروشگاه یافت نشد");
            }
            var marketer = await _repository.FindAsync(shop.MarketerId);

            if (marketer == null)
            {
                throw new DomainException("بازاریاب یافت نشد");
            }
            var newMarketer = await _repository.FindAsync(command.NewMarketerId);

            if (newMarketer == null)
            {
                throw new DomainException("بازاریاب جدید یافت نشد");
            }
            shop.MarketerId = newMarketer.Id;
            if (newMarketer.Equals(marketer))
            {
                throw new DomainException("بازایاب انتخابی شما با بازاریاب کنونی یکی است");
            }
            DomainEventDispatcher.Raise(new DetachedShopMarketersHistoryEvent(shop, marketer,
                                                                              new UserInfo(command.UserInfo.UserId, command.UserInfo.FirstName, command.UserInfo.LastName)));
            DomainEventDispatcher.Raise(new AssignmentShopMarketersHistoryEvent(shop, marketer,
                                                                                new UserInfo(command.UserInfo.UserId, command.UserInfo.FirstName, command.UserInfo.LastName)));
            return(new MarketerCommandResponse());
        }
        public async Task <AddProductToPercentDiscountCommandResponse> Handle(AddProductToPercentDiscountCommand command)
        {
            var product = await _productRepository.AsQuery()
                          .SingleOrDefaultAsync(p => p.Id == command.ProductId);

            if (product == null)
            {
                throw new DomainException("محصولی یافت نشد");
            }
            var discount = await _percentRepository.AsQuery()
                           .SingleOrDefaultAsync(p => p.Id == command.PercentDiscount);

            if (discount == null)
            {
                throw new DomainException("تخفیف یافت نشد");
            }
            if (discount.ProductDiscounts.Count >= discount.MaxProductCount)
            {
                throw new DomainException("حداکثر تعداد محصول در این تخفیف تکمیل شده است");
            }
            if (discount.ProductDiscounts.Any(p => p.Product.Id == command.ProductId))
            {
                throw new DomainException("این محصول در این تخفیف موجود می باشد");
            }
            var userInfo = new UserInfo(command.UserInfoCommand.UserId, command.UserInfoCommand.FirstName,
                                        command.UserInfoCommand.LastName);
            var productPercentDiscounts = new ProductDiscount(Guid.NewGuid(), product, userInfo);

            DomainEventDispatcher.Raise(new CreatePercentDiscountEvent(discount.Id, command.ProductId, discount.Title,
                                                                       userInfo, discount.FromDate, discount.ToDate,
                                                                       discount.Percent, discount.FromTime, discount.ToTime, DiscountType.PercentDiscount));
            discount.ProductDiscounts.Add(productPercentDiscounts);
            return(new AddProductToPercentDiscountCommandResponse());
        }
        public void Check_DomainEvents_ProjectAdded_Raise()
        {
            //given

            //existing project
            var project = Project.From(EntityId.From(1u), Description.From("descriptionText"));

            var taskOptionsBuilder = new DbContextOptionsBuilder <ActivityDbContext>();

            taskOptionsBuilder.UseSqlite("Data Source=todoagility_projectAdded_test.db;");
            var taskDbContext = new ActivityDbContext(taskOptionsBuilder.Options);
            var repTask       = new ActivityRepository(taskDbContext);

            using var taskDbSession = new DbSession <IActivityRepository>(taskDbContext, repTask);

            var handlerActivityAdded = new ProjectAddedHandler(taskDbSession);
            var dispatcher           = new DomainEventDispatcher();

            dispatcher.Subscribe(typeof(ProjectAddedEvent).FullName, handlerActivityAdded);

            //when
            dispatcher.Publish(ProjectAddedEvent.For(project));

            //then
            var projectId = EntityId.From(1u);
            var proj      = repTask.GetProject(projectId);

            Assert.NotNull(proj);
        }
        public void Check_UpdateActivityCommandHandler_Succeed()
        {
            var description        = "Given Description";
            var id                 = 1u;
            var projectId          = 1u;
            var dispatcher         = new DomainEventDispatcher();
            var taskOptionsBuilder = new DbContextOptionsBuilder <ActivityDbContext>();

            taskOptionsBuilder.UseSqlite("Data Source=todoagility_cqrs_test.db;");
            var taskDbContext = new ActivityDbContext(taskOptionsBuilder.Options);
            var repTask       = new ActivityRepository(taskDbContext);

            using var taskDbSession = new DbSession <IActivityRepository>(taskDbContext, repTask);

            var project      = Project.From(EntityId.From(projectId), Description.From(description));
            var originalTask = Activity.From(Description.From(description), EntityId.From(id),
                                             EntityId.From(projectId), ActivityStatus.From(1));

            taskDbSession.Repository.AddProject(project);
            taskDbSession.Repository.Add(originalTask);
            taskDbSession.SaveChanges();

            var descriptionNew = "Given Description Changed";
            var command        = new UpdateActivityCommand(id, descriptionNew);

            var handler = new UpdateActivityCommandHandler(taskDbSession, dispatcher);

            handler.Execute(command);

            var task = taskDbSession.Repository.Get(EntityId.From(id));

            Assert.NotEqual(task, originalTask);
        }
        public void Check_ChangeStatusActivityCommandHandler_Failed()
        {
            var description    = "Given Description";
            var id             = 1u;
            var newStatus      = 4;
            var projectId      = 1u;
            var dispatcher     = new DomainEventDispatcher();
            var optionsBuilder = new DbContextOptionsBuilder <ActivityDbContext>();

            optionsBuilder.UseSqlite("Data Source=todoagility_cqrs_changed_failed_test.db;");
            var taskDbContext = new ActivityDbContext(optionsBuilder.Options);
            var repTask       = new ActivityRepository(taskDbContext);

            using var taskDbSession = new DbSession <IActivityRepository>(taskDbContext, repTask);

            var originalTask = Activity.From(Description.From(description), EntityId.From(id),
                                             EntityId.From(projectId), ActivityStatus.From(1));

            taskDbSession.Repository.Add(originalTask);
            taskDbSession.SaveChanges();

            var command = new ChangeActivityStatusCommand(id, newStatus);

            var handler = new ChangeActivityStatusCommandHandler(taskDbSession, dispatcher);
            var result  = handler.Execute(command);

            Assert.False(result.IsSucceed);
        }
        public void Assign()
        {
            var dispatcher = new Mock <IDomainEventDispatcher>();

            DomainEventDispatcher.Assign(dispatcher.Object);

            Assert.AreSame(dispatcher.Object, DomainEventDispatcher.Current);
        }
Example #12
0
        public void NotReturningAnEmptyListOfAvailableHandlers()
        {
            var container              = ContainerSetup.BaseAutofacInitialization();
            var domainEventDispatcher  = new DomainEventDispatcher(container);
            var todoItemCompletedEvent = new TodoItemCompletedEvent(new TodoItem());

            var handlersForEvent = domainEventDispatcher.GetWrappedHandlers(todoItemCompletedEvent);

            Assert.IsNotEmpty(handlersForEvent);
        }
Example #13
0
 public ForgotPasswordModel(UserManager <ApplicationUser> userManager,
                            IEmailSender emailSender,
                            DomainEventDispatcher dispatcher,
                            ILogger <ForgotPasswordModel> logger)
 {
     _userManager = userManager;
     _emailSender = emailSender;
     _dispatcher  = dispatcher;
     _logger      = logger;
 }
            public void Test()
            {
                var dispatched = false;

                using (DomainEventDispatcher.Subscribe <AddedNewTodoList>(@event => { dispatched = true; }))
                {
                    var _ = new TodoList(
                        new TodoListId(Guid.NewGuid()), "Before my 40th birthday");
                }
                Assert.IsTrue(dispatched);
            }
        public void NotReturnAnEmptyListOfAvailableHandlers()
        {
            var builder = new ContainerBuilder();

            builder.RegisterModule(new DefaultInfrastructureModule(isDevelopment: true));
            var container = builder.Build();

            var domainEventDispatcher  = new DomainEventDispatcher(container);
            var toDoItemCompletedEvent = new ToDoItemCompletedEvent(new ToDoItem());

            var handlersForEvent = domainEventDispatcher.GetWrappedHandlers(toDoItemCompletedEvent);

            Assert.NotEmpty(handlersForEvent);
        }
Example #16
0
        public void OnBeforeScenario()
        {
            DomainEventDispatcher.Reset();

            container.RegisterInstance <IDateTimeProvider, TestDateTimeProvider>();
            Domain.Bootstrapping.Bootstrapper.Bootstrap(container);

            container.ResolveMutipleTypes()
            .ThatImplementOpenType(typeof(ICommandHandler <>))
            .ForEach(handler => specFlowContainer.RegisterInstanceAs(handler));

            specFlowContainer.RegisterInstanceAs(container.Resolve <IDateTimeProvider>());
            specFlowContainer.RegisterInstanceAs(container.Resolve <Repository>());
        }
Example #17
0
        public async Task <CreateShopCommandResponse> Handle(CreateShopCommand command)
        {
            var shopNumber = _seqRepository.GetNextSequenceValue(SqNames.ShopNumberSequence);
            var marketer   = await _marketerRepository.AsQuery().SingleOrDefaultAsync(p => p.BarcodeId == command.BarcodeId);

            if (marketer == null)
            {
                throw new DomainException("بازاریاب یافت نشد");
            }
            _marketerDomainService.CheckMarketerActive(marketer);
            _marketerDomainService.CheckMaxMarketerAllowedIsEnough(marketer);
            _personDomainService.CheckShopIsExist(command.UserId);
            var city = _cityRepository.Find(command.Address.CityId);

            if (city == null)
            {
                throw new DomainException("شهر وارد شده یافت نشد");
            }
            var appSetting = await _applicationSettingRepository.AsQuery().SingleOrDefaultAsync();

            if (appSetting == null)
            {
                throw new DomainException("تنظیمات برنامه یافت نشد");
            }
            if (command.DefaultDiscount < appSetting.MinimumDiscount || command.DefaultDiscount > appSetting.MaximumDiscount)
            {
                throw new DomainException("تخفیف پیش فرض در بازه تخفیفات معتبر نمی باشد");
            }
            var address = new ShopAddress(city.Id, city.Code, city.CityName, command.Address.AddressText,
                                          command.Address.PhoneNumber, command.Address.Position.ToDbGeography(),
                                          command.Address.ShopMobileNumber, command.Address.ZoneId,
                                          city.Province.Id, city.Province.Code, city.Province.Name);
            var accountBank   = new BankAccount(command.BankAccount.Iban, command.BankAccount.AccountOwnerName, command.BankAccount.AccountNumber);
            var imageDocument = new ImageDocuments(command.ImageDocuments.FaceImage, command.ImageDocuments.NationalCardImage);
            var shop          = new Shop(Guid.NewGuid(), command.Name, command.FirstName, command.LastName, command.EmailAddress,
                                         command.UserId, command.Description, command.NationalCode, address, accountBank, imageDocument,
                                         command.MobileNumber, command.AreaRadius, command.Metrage, command.DefaultDiscount, marketer.Id, shopNumber)
            {
                AppInfos        = new List <AppInfo>(),
                CustomerSubsets = new List <ShopCustomerSubset>()
            };

            _repository.Add(shop);
            DomainEventDispatcher.Raise(new AssignmentShopMarketersHistoryEvent(shop, marketer,
                                                                                new UserInfo(command.UserId, command.MobileNumber, "کاربر موبایل")));
            DomainEventDispatcher.Raise(new AddPanelNotificationEvent(Guid.NewGuid(), command.Name, "فروشگاه ایجاد شد",
                                                                      PanelNotificationType.ShopCreated, shop.Id.ToString()));
            return(new CreateShopCommandResponse());
        }
        public void NotReturnAnEmptyListOfAvailableHandlers()
        {
            var builder = new ContainerBuilder();
            builder.RegisterModule(new DefaultInfrastructureModule(isDevelopment: true));
            builder.RegisterType<NullLoggerFactory>().As<ILoggerFactory>().SingleInstance();
            builder.RegisterGeneric(typeof(Logger<>)).As(typeof(ILogger<>)).SingleInstance();
            var container = builder.Build();

            var domainEventDispatcher = new DomainEventDispatcher(container);
            var toDoItemCompletedEvent = new ToDoItemCompletedEvent(new ToDoItem());

            var handlersForEvent = domainEventDispatcher.GetWrappedHandlers(toDoItemCompletedEvent);

            Assert.NotEmpty(handlersForEvent);
        }
        public void NotReturnAnEmptyListOfAvailableHandlers()
        {
            // Arrange
            IServiceCollection container = new ServiceCollection();

            container.AddAppCoreServices();

            var domainEventDispatcher  = new DomainEventDispatcher(container.BuildServiceProvider());
            var toDoItemCompletedEvent = new ToDoItemCompletedEvent(new ToDoItem());

            // Act
            var handlersForEvent = domainEventDispatcher.GetWrappedHandlers(toDoItemCompletedEvent);

            // Assert
            Assert.NotEmpty(handlersForEvent);
        }
Example #20
0
        public static void AddEventuateTramDomainEventDispatcher(
            this IServiceCollection serviceCollection, string subscriberId,
            Func <IServiceProvider, DomainEventHandlers> domainEventHandlersFactory)
        {
            serviceCollection.TryAddSingleton <IEventTypeNamingStrategy, AttributeEventTypeNamingStrategy>();
            serviceCollection.AddSingleton(provider =>
            {
                var messageConsumer         = provider.GetRequiredService <IMessageConsumer>();
                var logger                  = provider.GetRequiredService <ILogger <DomainEventDispatcher> >();
                var eventTypeNamingStrategy = provider.GetRequiredService <IEventTypeNamingStrategy>();

                var dispatcher = new DomainEventDispatcher(subscriberId, domainEventHandlersFactory(provider),
                                                           messageConsumer, eventTypeNamingStrategy, logger);

                return(dispatcher);
            });
        }
Example #21
0
        public void Handle(CreateFactorEvent @event)
        {
            _factorDomainService.FactorIsExist(@event.OrderId);
            var factorAddress = new FactorAddress(@event.OrderBase.OrderAddress.AddressText,
                                                  @event.OrderBase.OrderAddress.PhoneNumber, @event.OrderBase.OrderAddress.CityId,
                                                  @event.OrderBase.OrderAddress.CityName, @event.OrderBase.OrderAddress.Geography);
            var shopDiscountPrice = decimal.Round(@event.Price * (100 - @event.Discount) / 100);
            var factor            = new Factor(@event.FactorId, @event.OrderId, @event.Price,
                                               @event.OrderSuggestionId, @event.Discount, @event.Customer,
                                               @event.Shop, factorAddress, shopDiscountPrice,
                                               CalcRealPrice(@event.FactorRaws, @event.Discount),
                                               @event.ShippingTime)
            {
                FactorRaws = @event.FactorRaws
            };

            _repository.Add(factor);
            DomainEventDispatcher.Raise(new CreateHasFactorEvent(@event.OrderId, @event.Shop.Id, factor));
        }
        public async Task <MarketerCommandResponse> Handle(DetachedMarketerShopCommand command)
        {
            var marketer = await _repository.FindAsync(command.MarketerId);

            if (marketer == null)
            {
                throw new DomainException("بازاریاب یافت نشد");
            }
            var shop = await _shopRepository.FindAsync(command.ShopId);

            if (shop == null)
            {
                throw new DomainException("فروشگاه یافت نشد");
            }
            shop.MarketerId = null;
            var userInfo = new UserInfo(command.UserInfo.UserId, command.UserInfo.FirstName, command.UserInfo.LastName);

            DomainEventDispatcher.Raise(new DetachedShopMarketersHistoryEvent(shop, marketer, userInfo));
            return(new MarketerCommandResponse());
        }
        public async Task <UpdateDiscountPercentCommandResponse> Handle(UpdateDiscountPercentCommand command)
        {
            var discount = await _percentRepository.AsQuery().SingleOrDefaultAsync(p => p.Id == command.Id);

            if (discount == null)
            {
                throw new DomainException("تخفیفی یافت نشد");
            }
            _percentDiscountDomainService.ValidationSettingDiscount(command.MaxOrderCount,
                                                                    discount.RemainOrderCount, command.MaxProductCount,
                                                                    discount.ProductDiscounts.Count);
            discount.FromTime        = command.FromTime;
            discount.ToTime          = command.ToTime;
            discount.MaxOrderCount   = command.MaxOrderCount;
            discount.MaxProductCount = command.MaxProductCount;
            discount.Title           = command.Title;
            discount.Description     = command.Description;
            DomainEventDispatcher.Raise(new UpdatePercentDiscountEvent(discount.Id, command.Title, command.FromDate.ConvertToDate(), command.ToDate.ConvertToDate()));
            discount.UserInfo = new UserInfo(command.UserInfoCommand.UserId, command.UserInfoCommand.FirstName, command.UserInfoCommand.LastName);
            return(new UpdateDiscountPercentCommandResponse());
        }
Example #24
0
        static void Main(string[] args)
        {
            // we create the domain event dispatcher and inject it into the objects of our domain model (normally done using a IoC container)
            IDomainEventDispatcher dispatcher = new DomainEventDispatcher();
            Player  j1      = new Player1(dispatcher);
            Player  j2      = new Player2(dispatcher);
            Match   match   = new Match(dispatcher);
            Outcome outcome = new Outcome(dispatcher);

            bool exit = false;

            while (!exit)
            {
                PlayType jugada = PlayType.None;
                do
                {
                    Console.WriteLine("Jugador1: Piedra(1) Papel(2) o Tijera(3)");
                    var s = Console.ReadLine();
                    jugada = JugadaSeleccionada(s);
                    j1.Play(jugada);
                    j1.Confirm();
                } while (jugada == PlayType.None);
                do
                {
                    Console.WriteLine("Jugador2: Piedra(1) Papel(2) o Tijera(3)");
                    var s = Console.ReadLine();
                    jugada = JugadaSeleccionada(s);
                    j2.Play(jugada);
                    j2.Confirm();
                } while (jugada == PlayType.None);
                Console.WriteLine("exit? y/n");
                var r = Console.ReadLine();
                exit = r == "y";
            }

            match.End();
            Console.WriteLine($"Ganador {outcome.LastWinner()}");
            Console.ReadLine();
        }
        public void Check_AddActivityCommandHandler_Succeed()
        {
            var description        = "Given Description";
            var projectId          = 1u;
            var dispatcher         = new DomainEventDispatcher();
            var taskOptionsBuilder = new DbContextOptionsBuilder <ActivityDbContext>();

            taskOptionsBuilder.UseSqlite("Data Source=todoagility_add_test.db;");
            var taskDbContext = new ActivityDbContext(taskOptionsBuilder.Options);
            var repTask       = new ActivityRepository(taskDbContext);

            using var taskDbSession = new DbSession <IActivityRepository>(taskDbContext, repTask);
            taskDbSession.Repository.AddProject(Project.From(EntityId.From(projectId), Description.From(description)));
            taskDbSession.SaveChanges();

            var handler = new AddActivityCommandHandler(dispatcher, taskDbSession);
            var command = new AddActivityCommand(description, projectId);

            handler.Execute(command);

            var task = taskDbSession.Repository.Find(a => a.ProjectId == projectId);

            Assert.NotNull(task);
        }
 protected override void BeforeApplyChange(object @event)
 {
     DomainEventDispatcher.Publish(@event);
 }
Example #27
0
        public async Task <CreateOrderSuggestionCommandResponse> Handle(CreateOrderSuggestionCommand command)
        {
            _applicationSettingDomainService.CheckDiscountInRangeSetting(command.Discount);
            _applicationSettingDomainService.CheckShippingTime(command.ShippingTime);
            if (_repository.AsQuery().Any(p => p.OrderId == command.OrderId))
            {
                throw new DomainException("پیشنهاد بروی این سفارش زده شده است");
            }
            var order = _orderRepository.AsQuery().SingleOrDefault(p => p.Id == command.OrderId);

            if (order == null)
            {
                throw new DomainException("سفارش یافت نشد");
            }

            if (order.OrderStatus == OrderStatus.Cancel)
            {
                throw new DomainException("این سفارش توسط مشتری لغو شده است");
            }
            _applicationSettingDomainService.CheckOrderExpireTime(order.CreationTime);
            if (order.ResponseExpireTime < DateTime.Now)
            {
                throw new DomainException("زمان پاسخ گویی شما به پایان رسیده است");
            }

            var shop = _personRepository.AsQuery().OfType <Shop>().SingleOrDefault(p => p.UserId == command.UserId);

            if (shop == null)
            {
                throw new DomainException("فروشگاه یافت نشد");
            }

            var appSetting = _applicationSettingRepository.AsQuery().SingleOrDefault();

            if (appSetting == null)
            {
                throw new Exception();
            }

            if (command.Discount < appSetting.MinimumDiscount || command.Discount > appSetting.MaximumDiscount)
            {
                throw new DomainException("تخفیف وارد شده در بازه تخفیفات معتبر نمی باشد");
            }
            if (command.ShippingTime > appSetting.MaximumDeliveryTime)
            {
                throw new DomainException("زمان ارسال سفارش از حداکثر زمان ارسال معتبر بیشتر می باشد");
            }

            var orderId         = order is AreaOrder areaOrder ? areaOrder.PrivateOrder.Id : order.Id;
            var orderSuggestion = new OrderSuggestion(Guid.NewGuid(), orderId, command.Discount, command.Description, shop, command.ShippingTime)
            {
                OrderSuggestionItems = new List <OrderSuggestionItemBase>()
            };
            decimal totalPrice = 0;

            foreach (var item in command.OrderSuggestionItems)
            {
                var orderItem = order.OrderItems.SingleOrDefault(p => p.Id == item.OrderItemId);
                if (orderItem == null)
                {
                    throw new DomainException("آیتم سفارش یافت نشد");
                }
                var findProduct = _productRepository.Find(item.ProductId);
                switch (item.OrderSuggestionItemType)
                {
                case OrderSuggestionItemType.AlternativeProduct:
                    if (findProduct == null)
                    {
                        throw new DomainException("کالای ارسالی جایگزین نامعتبر می باشد");
                    }
                    var alternativeProduct =
                        new AlternativeProductSuggestion(findProduct.Id, findProduct.Name, findProduct.MainImage,
                                                         findProduct.Brand.Id, findProduct.Brand.Name);
                    orderItem.Discount = null;
                    var alternativeProductSuggestionItem = new AlternativeProductSuggestionItem(Guid.NewGuid(),
                                                                                                orderItem, item.Quantity, item.Description, item.Price, alternativeProduct,
                                                                                                orderItem.Quantity != item.Quantity);
                    orderSuggestion.OrderSuggestionItems.Add(alternativeProductSuggestionItem);
                    totalPrice = totalPrice + (item.Price * item.Quantity);
                    break;

                case OrderSuggestionItemType.NoProduct:
                    var noProduct = new NoProductSuggestionItem(Guid.NewGuid(), orderItem);
                    orderSuggestion.OrderSuggestionItems.Add(noProduct);
                    break;

                case OrderSuggestionItemType.HasProduct:
                    if (orderItem.Discount != null)
                    {
                        if (!orderItem.Discount.HasDiscountValid())
                        {
                            orderItem.Discount = null;
                        }
                    }
                    var hasProduct = new HasProductSuggestionItem(Guid.NewGuid(), orderItem, item.Quantity,
                                                                  item.Description, item.Price, orderItem.Quantity != item.Quantity);
                    orderSuggestion.OrderSuggestionItems.Add(hasProduct);
                    totalPrice = totalPrice + (item.Price * item.Quantity);
                    break;
                }
            }
            _repository.Add(orderSuggestion);


            //todo order check it
            var expireMinutes = order.ExpireOpenTime.Subtract(DateTime.Now).TotalMinutes;

            order.ExpireOpenTime = order.ExpireOpenTime.AddMinutes(appSetting.OrderSuggestionExpireTime - expireMinutes);
            order.SuggestionTime = DateTime.Now.AddMinutes(appSetting.OrderSuggestionExpireTime);
            DomainEventDispatcher.Raise(new TheOrderStatusWentToHasSuggestionEvent(order));
            if (order is AreaOrder area)
            {
                area.PrivateOrder.SuggestionTime = DateTime.Now.AddMinutes(appSetting.OrderSuggestionExpireTime);
                DomainEventDispatcher.Raise(new TheOrderStatusWentToHasSuggestionEvent(area.PrivateOrder));
            }
            DomainEventDispatcher.Raise(new CreateHasSuggestionsEvent(order.Id, shop.Id, orderSuggestion));
            await _fcmNotification.SendToIds(order.Customer.GetPushTokens(),
                                             "پیشنهاد سفارش",
                                             $"برای سفارش شما با شناسه {order.Id} یک پیشنهاد ثبت شد",
                                             NotificationType.OrderSuggestionAdded,
                                             AppType.Customer, NotificationSound.Shopper);

            return(new CreateOrderSuggestionCommandResponse());
        }
 /// <summary>
 /// Called after an event has been applied, exposed as a point of interception.
 /// </summary>
 /// <param name="event">The event that has been applied.</param>
 protected virtual void AfterApplyChange(object @event)
 {
     DomainEventDispatcher.Publish(@event);
 }
        public async Task <CreatePrivateOrderCommandResponse> Handle(CreatePrivateOrderCommand command)
        {
            var appSetting = _applicationSettingRepository.AsQuery().FirstOrDefault();

            if (appSetting == null)
            {
                throw new Exception();
            }
            var customer = _personRepository.AsQuery().OfType <Customer>().SingleOrDefault(p => p.UserId == command.UserId);

            if (customer == null)
            {
                throw new DomainException("مشتری یافت نشد");
            }
            await _orderDomainService.CheckCustomerRequestOrderDuration(customer, appSetting);

            var customerAddress =
                customer.CustomerAddresses.SingleOrDefault(p => p.Id == command.CustomerAddressId);

            if (customerAddress == null)
            {
                throw new DomainException("ادرس مشتری یافت نشد");
            }
            var shop = _personRepository.AsQuery().OfType <Shop>().SingleOrDefault(p => p.Id == command.ShopId);

            if (shop == null)
            {
                throw new DomainException("فروشگاه وارد شده یافت نشد");
            }
            var orderAddress = new OrderAddress(customerAddress.AddressText, customerAddress.PhoneNumber,
                                                customerAddress.CityId, customerAddress.CityName, customerAddress.Geography);
            var privateOrder = new PrivateOrder(customer, orderAddress, command.Description, DateTime.Now.AddSeconds(appSetting.OrderExpireOpenTime), shop)
            {
                OrderItems = new List <OrderItem>()
            };

            if (command.OrderItems.Any(p => p.IsPercentDiscount))
            {
                if (_factorDomainService.HavePercentDiscountToday(customer))
                {
                    throw new DomainException("شما مجاز به انتخاب یک کالای دارای تخفیف درصدی در هر روز می باشید");
                }
            }
            decimal totalPrice = 0;

            foreach (var orderItem in command.OrderItems)
            {
                var product = _productRepository.Find(orderItem.ProductId);
                if (product == null)
                {
                    throw new DomainException("کالای انتخابی یافت نشد");
                }
                var orderProduct = new OrderProduct(product.Id, product.Name, product.Price, product.MainImage, product.Brand.Id, product.Brand.Name);
                OrderItemDiscountBase orderItemDiscount = null;
                if (orderItem.IsPercentDiscount)
                {
                    if (product.ProductDiscount != null)
                    {
                        if (product.ProductDiscount is ProductPercentDiscount productPercentDiscount)
                        {
                            if (productPercentDiscount.HasDiscountValid())
                            {
                                var haveRemainOrderCount = _percentDiscountDomainService.HaveRemainOrderCount(productPercentDiscount.DiscountId, customer);
                                if (haveRemainOrderCount)
                                {
                                    orderItemDiscount = new OrderItemPercentDiscount(Guid.NewGuid(),
                                                                                     productPercentDiscount.DiscountId, productPercentDiscount.Title, productPercentDiscount.FromDate,
                                                                                     productPercentDiscount.ToDate, productPercentDiscount.Percent, productPercentDiscount.FromTime,
                                                                                     productPercentDiscount.ToTime);
                                    _percentDiscountDomainService.LowOfNumberRemainOrderCount(productPercentDiscount.DiscountId, customer);
                                }
                            }
                        }
                    }
                }
                privateOrder.OrderItems.Add(new OrderItem(Guid.NewGuid(), orderItem.Quantity,
                                                          orderItem.Description, orderProduct, orderItemDiscount));
                totalPrice = totalPrice + (product.Price * orderItem.Quantity);
            }
            if (privateOrder.OrderItems.Count(item => item.Discount != null) > 1)
            {
                throw new DomainException("شما مجاز به انتخاب یک کالای دارای تخفیف درصدی در هر روز می باشید");
            }
            _applicationSettingDomainService.CheckMinimumBuy(totalPrice);
            _orderDomainService.CalcOrderPercentDiscount(privateOrder);
            _privateOrderRepository.Add(privateOrder);
            DomainEventDispatcher.Raise(new CreateShopOrderLogEvent(shop, privateOrder));
            _context.SaveChanges();
            await _fcmNotification.SendToIds(shop.GetPushTokens(), "سفارش جدید",
                                             $"یک سفارش ثبت شد", NotificationType.OrderAdd,
                                             AppType.Shop, NotificationSound.Shopper);

            SendNotificationToBoss(privateOrder, shop, customer);
            return(new CreatePrivateOrderCommandResponse(privateOrder.Id, appSetting.OrderExpireOpenTime));
        }
Example #30
0
        public async Task <AcceptOrderSuggestionCommandResponse> Handle(AcceptOrderSuggestionCommand command)
        {
            var setting = _applicationSettingRepository.AsQuery().FirstOrDefault();

            var orderSuggestion = await _repository.AsQuery().SingleOrDefaultAsync(p => p.Id == command.OrderSuggestionId);

            if (orderSuggestion == null)
            {
                throw new DomainException("پیشنهاد سفارش یافت نشد");
            }
            var order = _orderRepository.AsQuery().SingleOrDefault(p => p.Id == orderSuggestion.OrderId);

            if (order == null)
            {
                throw new DomainException("سفارش یافت نشد");
            }

            if (DateTime.Now > orderSuggestion.CreationTime.AddMinutes(setting.OrderSuggestionExpireTime))
            {
                throw new DomainException("زمان تایید پیشنهاد پایان یافته است");
            }
            var selectedOrderSuggestionItems =
                orderSuggestion.OrderSuggestionItems.Where(p => command.AcceptOrderSuggestionItem.Any(i => i.OrderSuggestionItemId == p.Id))
                .ToList();
            long factorId = _seqRepository.GetNextSequenceValue(SqNames.FactorIdSequence);

            List <FactorRaw> factorRaws = new List <FactorRaw>();

            var havePercentDiscountToday = _orderDomainService.CheckOrderPercentDiscountToday(order.Customer, orderSuggestion.OrderId);

            foreach (var selectedOrderSuggestionItem in selectedOrderSuggestionItems)
            {
                switch (selectedOrderSuggestionItem)
                {
                case AlternativeProductSuggestionItem alternativeProductSuggestionItem:
                {
                    var itemQuantity = command.AcceptOrderSuggestionItem.SingleOrDefault(p =>
                                                                                         p.OrderSuggestionItemId == selectedOrderSuggestionItem.Id);
                    var quantity = itemQuantity?.Quantity ?? alternativeProductSuggestionItem.Quantity;
                    var product  = _productRepository.Find(alternativeProductSuggestionItem
                                                           .AlternativeProductSuggestion.ProductId);
                    if (product == null)
                    {
                        throw new DomainException("محصول جایگزین یافت نشد");
                    }
                    var factorRaw = new FactorRaw(product.Id, quantity,
                                                  alternativeProductSuggestionItem.Description,
                                                  alternativeProductSuggestionItem.Price, product.Name,
                                                  alternativeProductSuggestionItem.AlternativeProductSuggestion
                                                  .ProductImage, product.Brand.Id, product.Brand.Name, null);
                    factorRaws.Add(factorRaw);
                    break;
                }

                case HasProductSuggestionItem hasProductSuggestionItem:
                {
                    var itemQuantity = command.AcceptOrderSuggestionItem.SingleOrDefault(p =>
                                                                                         p.OrderSuggestionItemId == selectedOrderSuggestionItem.Id);
                    var       quantity = itemQuantity?.Quantity ?? hasProductSuggestionItem.Quantity;
                    var       product  = _productRepository.Find(hasProductSuggestionItem.OrderItem.OrderProduct.ProductId);
                    FactorRaw factorRaw;
                    if (havePercentDiscountToday)
                    {
                        if (hasProductSuggestionItem.OrderItem.Discount != null)
                        {
                            if (hasProductSuggestionItem.OrderItem.Discount is OrderItemPercentDiscount
                                orderItemPercentDiscount)
                            {
                                if (orderItemPercentDiscount.HasDiscountValid())
                                {
                                    factorRaw = new FactorRaw(product.Id, quantity,
                                                              hasProductSuggestionItem.Description,
                                                              hasProductSuggestionItem.Price, product.Name,
                                                              hasProductSuggestionItem.OrderItem.OrderProduct.ProductImage,
                                                              product.Brand.Id, product.Brand.Name,
                                                              new FactorRawPercentDiscount(Guid.NewGuid(),
                                                                                           orderItemPercentDiscount.DiscountId,
                                                                                           orderItemPercentDiscount.DiscountTitle,
                                                                                           orderItemPercentDiscount.FromDate, orderItemPercentDiscount.ToDate,
                                                                                           orderItemPercentDiscount.Percent, orderItemPercentDiscount.FromTime,
                                                                                           orderItemPercentDiscount.ToTime));
                                }
                                else
                                {
                                    factorRaw = new FactorRaw(product.Id, quantity,
                                                              hasProductSuggestionItem.Description,
                                                              hasProductSuggestionItem.Price, product.Name,
                                                              hasProductSuggestionItem.OrderItem.OrderProduct.ProductImage,
                                                              product.Brand.Id,
                                                              product.Brand.Name, null);
                                }
                            }
                            else
                            {
                                factorRaw = new FactorRaw(product.Id, quantity,
                                                          hasProductSuggestionItem.Description,
                                                          hasProductSuggestionItem.Price, product.Name,
                                                          hasProductSuggestionItem.OrderItem.OrderProduct.ProductImage,
                                                          product.Brand.Id,
                                                          product.Brand.Name, null);
                            }
                        }
                        else
                        {
                            factorRaw = new FactorRaw(product.Id, quantity,
                                                      hasProductSuggestionItem.Description,
                                                      hasProductSuggestionItem.Price, product.Name,
                                                      hasProductSuggestionItem.OrderItem.OrderProduct.ProductImage, product.Brand.Id,
                                                      product.Brand.Name, null);
                        }
                    }
                    else
                    {
                        factorRaw = new FactorRaw(product.Id, quantity,
                                                  hasProductSuggestionItem.Description,
                                                  hasProductSuggestionItem.Price, product.Name,
                                                  hasProductSuggestionItem.OrderItem.OrderProduct.ProductImage, product.Brand.Id,
                                                  product.Brand.Name, null);
                    }
                    factorRaws.Add(factorRaw);
                    break;
                }
                }
            }
            DomainEventDispatcher.Raise(new TheOrderStatusWentToAcceptEvent(order));
            DomainEventDispatcher.Raise(new CreateFactorEvent(factorId, order.Id, orderSuggestion.Id,
                                                              CalcTotalPrice(factorRaws), orderSuggestion.Discount,
                                                              factorRaws, orderSuggestion.Shop, order.Customer, order, orderSuggestion.ShippingTime));
            orderSuggestion.OrderSuggestionStatus = OrderSuggestionStatus.Accept;
            return(new AcceptOrderSuggestionCommandResponse(factorId));
        }