public async Task <BankTransferDetailsDto> Handle(GetBankTransferDetailsCommand request, CancellationToken cancellationToken) { var orderId = Guid.Parse(request.OrderId); var order = await _orderRepository.GetByIdAsync(orderId); if (order == null) { throw new NotFoundException("Order"); } var userClaims = _httpContext.User.Claims.ToTokenPayload().UserClaims; if (userClaims.Role.ToUpperInvariant() != "ADMIN" && userClaims.Id != order.BuyerId && userClaims.Id != order.SellerId) { throw new NotFoundException("Order"); } var identityServiceClient = _grpcServiceClientFactory.Create( _endpointsConfig.Identity.Grpc.ToString()); var grpcRequest = new GetBankAccountNumberRequest { UserId = order.SellerId }; var grpcResponse = await identityServiceClient.GetBankAccount(grpcRequest); var bankTransferDetails = new BankTransferDetailsDto { Title = $"Order {orderId}", TransferAmount = order.CalculateTotalPrice(), AccountNumber = grpcResponse.BankAccountNumber }; return(bankTransferDetails); }
public async Task <IList <DeliveryMethodDto> > Handle(GetAvailableDeliveryMethodsForOrderQuery request, CancellationToken cancellationToken) { var userId = _httpContext.User.Claims.ToTokenPayload().UserClaims.Id; var orderId = Guid.Parse(request.OrderId); var order = await _orderRepository.GetByIdAsync(orderId); if (order.BuyerId != userId) { throw new NotFoundException(); } var offerIds = order.OrderItems.Select(orderItem => orderItem.OfferId); var offersServiceClient = _offersServiceClientFactory.Create(_endpointsConfig.Offers.Grpc.ToString()); var grpcRequest = new GetDeliveryMethodsForOffersRequest { OfferIds = offerIds }; var grpcResponse = await offersServiceClient.GetDeliveryMethodsForOffers(grpcRequest); return(grpcResponse.DeliveryMethods.Select(method => new DeliveryMethodDto { Name = method.Name, Price = method.Price }).ToList()); }
public async Task <CartItemDto> Handle(AddToCartCommand request, CancellationToken cancellationToken) { var offerId = Guid.Parse(request.OfferId); var offersServiceClient = _offersServiceClientFactory.Create(_endpointsConfig.Offers.Grpc.ToString()); var grpcRequest = new GetOfferBasicInfoRequest { OfferId = offerId }; var grpcResponse = await offersServiceClient.GetOfferBasicInfo(grpcRequest); var offer = grpcResponse.Offer; if (!offer.IsActive) { throw new CartsDomainException("Offer is not active"); } if (request.Quantity > offer.AvailableStock) { throw new CartsDomainException($"Quantity out of range. AvailableStock for offer {offer.Id} is {offer.AvailableStock}"); } var userId = _httpContext.User.Claims.ToTokenPayload().UserClaims.Id; if (userId == offer.OwnerId) { throw new CartsDomainException("Buying from himself/herself is illegal"); } var cart = await _cartRepository.GetOrCreateByUserIdAsync(userId); var imageUri = offer.Images.FirstOrDefault(x => x.IsMain)?.Uri; var cartItem = new CartItem(cart.Id, cart.UserId, Guid.Parse(request.OfferId), offer.OwnerId, offer.Name, offer.Price, request.Quantity, offer.AvailableStock, imageUri); cart.AddCartItem(cartItem); _cartRepository.Update(cart); await _cartRepository.UnitOfWork.SaveChangesAndDispatchDomainEventsAsync(cancellationToken); _logger.LogWithProps(LogLevel.Debug, "Offer added to cart", "OfferId".ToKvp(request.OfferId), "CartId".ToKvp(cart.Id), "CartItemId".ToKvp(cartItem.Id)); return(cartItem.ToDto()); }
public async Task <Unit> Handle(UpdateDeliveryInfoCommand request, CancellationToken cancellationToken) { var userId = _httpContext.User.Claims.ToTokenPayload().UserClaims.Id; var orderId = Guid.Parse(request.OrderId); var order = await _orderRepository.GetByIdAsync(orderId); if (order == null || order.BuyerId != userId) { throw new NotFoundException(); } var deliveryAddress = new DeliveryAddress(request.FirstName, request.LastName, request.PhoneNumber, request.Country, request.City, request.ZipCode, request.Street); order.SetDeliveryAddress(deliveryAddress); var offerIds = order.OrderItems.Select(orderItem => orderItem.OfferId); var offersServiceClient = _offersServiceClientFactory.Create(_endpointsConfig.Offers.Grpc.ToString()); var grpcRequest = new GetDeliveryMethodsForOffersRequest { OfferIds = offerIds }; var grpcResponse = await offersServiceClient.GetDeliveryMethodsForOffers(grpcRequest); var matchingDeliveryMethod = grpcResponse.DeliveryMethods?.FirstOrDefault(x => x.Name == request.DeliveryMethodName); if (matchingDeliveryMethod == null) { throw new OrdersDomainException("Invalid delivery method name"); } var deliveryMethod = new DeliveryMethod(matchingDeliveryMethod.Name, matchingDeliveryMethod.Price); order.SetDeliveryMethod(deliveryMethod); _orderRepository.Update(order); await _orderRepository.UnitOfWork.SaveChangesAndDispatchDomainEventsAsync(cancellationToken); return(await Unit.Task); }
public async Task <Unit> Handle(RemoveOfferCommand request, CancellationToken cancellationToken) { var offerId = Guid.Parse(request.OfferId); var offer = await _offerRepository.GetByIdAsync(offerId); if (offer == null) { throw new NotFoundException(); } var userClaims = _httpContext.User.Claims.ToTokenPayload().UserClaims; var userId = userClaims.Id; var adminRoles = new List <string> { "ADMIN", "SUPER_ADMIN" }; if (offer.OwnerId != userId && !adminRoles.Contains(userClaims.Role)) { throw new ForbiddenException(); } var ordersServiceClient = _ordersServiceClientFactory.Create(_endpointsConfig.Orders.Grpc.ToString()); var grpcRequest = new GetOfferHasOrdersRequest { OfferId = offerId }; var grpcResponse = await ordersServiceClient.GetOfferHasOrders(grpcRequest); if (grpcResponse.OfferHasOrders) { throw new OffersDomainException("Offer cannot be cancelled because it's related to at least one order"); } offer.MarkAsRemoved(); _offerRepository.Update(offer); await _offerRepository.UnitOfWork.SaveChangesAndDispatchDomainEventsAsync(cancellationToken); return(await Unit.Task); }
public async Task <Guid> Handle(FinalizeCartCommand request, CancellationToken cancellationToken) { var userId = _httpContext.User.Claims.ToTokenPayload().UserClaims.Id; var cart = await _cartRepository.GetOrCreateByUserIdAsync(userId); if (cart.IsEmpty) { throw new CartsDomainException($"Cart {cart.Id} cannot be finalized because it's empty"); } var offersServiceClient = _offersServiceClientFactory.Create(_endpointsConfig.Offers.Grpc.ToString()); var offerIds = cart.CartItems.Select(x => x.OfferId).ToList(); var getOffersAvailabilityRequest = new GetOffersAvailabilityRequest { OfferIds = offerIds }; var getOffersAvailabilityResponse = await offersServiceClient.GetOffersAvailability(getOffersAvailabilityRequest); var notActiveOffers = getOffersAvailabilityResponse.OfferAvailabilities.Where(x => x.Availability != Availability.Active).ToList(); if (notActiveOffers.Any()) { foreach (var offer in notActiveOffers.Where(x => x.Availability == Availability.NotActive)) { await _eventBus.PublishAsync(new OfferBecameUnavailableIntegrationEvent { OfferId = offer.OfferId }); _logger.LogWithProps(LogLevel.Error, $"Published {nameof(OfferBecameUnavailableIntegrationEvent)} integration event", "CartId".ToKvp(cart.Id), "OfferId".ToKvp(offer.OfferId)); } var notExistingOffers = notActiveOffers.Where(x => x.Availability == Availability.DoesNotExist).ToList(); if (notExistingOffers.Any()) { foreach (var notExistingOffer in notExistingOffers) { _cartItemRepository.RemoveWithOfferId(notExistingOffer.OfferId); } await _cartItemRepository.UnitOfWork.SaveChangesAndDispatchDomainEventsAsync(cancellationToken); _logger.LogWithProps(LogLevel.Error, $"Removed not existing offers from cart", "CartId".ToKvp(cart.Id), "OffersIds".ToKvp(string.Join(",", notExistingOffers.Select(x => x.OfferId)))); } throw new CartsDomainException("At least offer is not active"); } var ordersServiceClient = _ordersServiceClientFactory.Create(_endpointsConfig.Orders.Grpc.ToString()); var createOrderRequest = PrepareCreateOrderRequest(cart); var createOrderResponse = await ordersServiceClient.CreateOrder(createOrderRequest); _logger.LogWithProps(LogLevel.Debug, "Order created from cart", "OrderId".ToKvp(createOrderResponse.OrderId), "CartId".ToKvp(cart.Id)); _cartRepository.Remove(cart); await _cartRepository.UnitOfWork.SaveChangesAndDispatchDomainEventsAsync(cancellationToken); _logger.LogWithProps(LogLevel.Debug, "Removed cart", "CartId".ToKvp(cart.Id)); return(createOrderResponse.OrderId); }