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); }
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); }
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); }
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>()); }
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); }
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); }); }
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()); }
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); }
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)); }
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)); }