Beispiel #1
0
        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);
        }
Beispiel #2
0
        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());
        }
Beispiel #3
0
        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());
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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);
        }