Example #1
0
        public virtual async Task CancelEditOrderAsync(Overture.ServiceModel.Orders.Order order)
        {
            if (order == null)
            {
                throw new ArgumentNullException(nameof(order));
            }

            try
            {
                await DeleteCartDraft(order).ConfigureAwait(false);
            }
            catch (ComposerException ex)
            {
                var ownedBySomeoneElseError = ex.Errors?.FirstOrDefault(e => e.ErrorCode == Constants.ErrorCodes.IsOwnedBySomeoneElse);
                if (ownedBySomeoneElseError != null)
                {
                    await ChangeOwnership(order).ConfigureAwait(false);
                    await DeleteCartDraft(order).ConfigureAwait(false);
                }
                else
                {
                    throw;
                }
            }

            ClearEditMode();
        }
Example #2
0
        public virtual async Task <bool> CanEdit(Overture.ServiceModel.Orders.Order order)
        {
            if (!ComposerContext.IsAuthenticated || !ValidateOrder(order))
            {
                return(false);
            }

            var orderSettings = await OrderRepository.GetOrderSettings(ComposerContext.Scope).ConfigureAwait(false);

            var shipmentStatuses = order.Cart.GetAllShipmentStatuses();

            if (!shipmentStatuses.Any() ||
                orderSettings == null ||
                string.IsNullOrWhiteSpace(orderSettings.EditableShipmentStates))
            {
                return(false);
            }

            var isOrderEditable = shipmentStatuses
                                  .All(item => orderSettings
                                       .EditableShipmentStates
                                       .ToLower()
                                       .Split('|')
                                       .Contains(item.ToLower()));

            return(isOrderEditable);
        }
Example #3
0
 protected CreateOrderDetailViewModelParam CreateOrderDetailViewModelParam(Overture.ServiceModel.Orders.Order order)
 {
     return(new CreateOrderDetailViewModelParam
     {
         CultureInfo = new CultureInfo("en-US"),
         OrderStatuses = new Dictionary <string, string>
         {
             { "InProgress", "In Progress" },
             { "Canceled", "Canceled" }
         },
         CountryCode = GetRandom.String(32),
         BaseUrl = GetRandom.String(32),
         Order = order,
         ProductImageInfo = new ProductImageInfo
         {
             ImageUrls = new List <ProductMainImage>()
         },
         ShipmentsNotes = new Dictionary <Guid, List <string> >(),
         OrderChanges = new List <OrderHistoryItem>(),
         ShipmentStatuses = new Dictionary <string, string>
         {
             { "InProgress", "In Progress" },
             { "Canceled", "Canceled" }
         }
     });
 }
        public async Task WHEN_valid_request_SHOULD_succeed()
        {
            //Arrange
            var order = new Overture.ServiceModel.Orders.Order
            {
                OrderNumber = GetRandom.String(10)
            };

            _container.GetMock <IOvertureClient>()
            .Setup(r => r.SendAsync(It.IsAny <GetOrderByNumberRequest>()))
            .ReturnsAsync(order);

            var orderRepository = _container.CreateInstance <OrderRepository>();

            //Act
            var param = new GetCustomerOrderParam
            {
                CustomerId  = Guid.NewGuid(),
                OrderNumber = GetRandom.String(10),
                Scope       = GetRandom.String(32),
            };

            var result = await orderRepository.GetOrderAsync(param).ConfigureAwait(false);

            //Assert
            result.Should().NotBeNull();
            result.OrderNumber.Should().BeEquivalentTo(order.OrderNumber);
        }
Example #5
0
        public void SetUp()
        {
            //Arrange
            _container = new AutoMocker();

            _container.Use(ViewModelMapperFactory.Create());
            _container.Use(CartViewModelFactoryMock.Create());

            var cartRepoMock = _container.GetMock <ICartRepository>();

            cartRepoMock.Setup(repo => repo.CompleteCheckoutAsync(It.IsNotNull <CompleteCheckoutParam>()))
            .Returns((CompleteCheckoutParam p) =>
            {
                var order = new Overture.ServiceModel.Orders.Order
                {
                    Cart = new ProcessedCart()
                    {
                        Customer = new CustomerSummary()
                        {
                            Email = GetRandom.Email()
                        },
                        Shipments = new System.Collections.Generic.List <Shipment>()
                        {
                            new Shipment
                            {
                                Id        = GetRandom.Guid(),
                                LineItems = new System.Collections.Generic.List <LineItem>()
                                {
                                    new LineItem
                                    {
                                        Id               = GetRandom.Guid(),
                                        Sku              = GetRandom.String(10),
                                        CatalogId        = GetRandom.String(10),
                                        PlacedPrice      = GetRandom.Decimal(),
                                        PlacedQuantity   = GetRandom.Int(),
                                        Status           = GetRandom.String(5),
                                        Total            = GetRandom.Decimal(),
                                        KvaValues        = new Overture.ServiceModel.PropertyBag(),
                                        KvaDisplayValues = new Overture.ServiceModel.PropertyBag(),
                                        ProductSummary   = new CartProductSummary
                                        {
                                            Brand                   = null,
                                            DisplayName             = GetRandom.String(10),
                                            PrimaryParentCategoryId = GetRandom.String(10)
                                        }
                                    }
                                },
                                FulfillmentMethod = new FulfillmentMethod
                                {
                                    FulfillmentMethodType = FulfillmentMethodType.PickUp
                                }
                            }
                        }
                    },
                    OrderNumber = GetRandom.String(12)
                };

                return(Task.FromResult(order));
            });
        }
Example #6
0
        public virtual async Task <CancellationStatus> GetCancellationStatus(Overture.ServiceModel.Orders.Order order)
        {
            if (!ComposerContext.IsAuthenticated || !ValidateOrder(order))
            {
                return(new CancellationStatus());
            }
            var orderFulfillmentState = await OrderRepository.GetOrderFulfillmentStateAsync(new GetOrderFulfillmentStateParam
            {
                OrderId = order.Id,
                ScopeId = order.ScopeId
            }).ConfigureAwait(false);

            if (orderFulfillmentState == null || OrderHistoryConfiguration.CompletedOrderStatuses.Contains(orderFulfillmentState.Status))
            {
                return(new CancellationStatus());
            }

            switch (orderFulfillmentState.IsCancelable)
            {
            case true when !orderFulfillmentState.IsProcessing && orderFulfillmentState.ShipmentFulfillmentStates.All(item => item.AllowedStatusChanges?.Contains(Constants.OrderStatus.Canceled) ?? false):
                return(new CancellationStatus()
                {
                    CanCancel = true, CancellationPending = false
                });

            case false when orderFulfillmentState.IsProcessing && HasCancellationMessage(orderFulfillmentState):
                return(new CancellationStatus()
                {
                    CanCancel = false, CancellationPending = true
                });

            default:
                return(new CancellationStatus());
            }
        }
Example #7
0
 private Task <Overture.ServiceModel.Orders.Order> SaveEditedOrder(Overture.ServiceModel.Orders.Order order)
 {
     return(OrderRepository.SubmitCartOrderDraftAsync(new SubmitCartOrderDraftParam
     {
         CustomerId = Guid.Parse(order.CustomerId),
         Scope = order.ScopeId,
         OrderId = Guid.Parse(order.Id)
     }));
 }
Example #8
0
        public virtual async Task <ProcessedCart> StartEditOrderModeAsync(Overture.ServiceModel.Orders.Order order)
        {
            if (order == null)
            {
                throw new ArgumentNullException(nameof(order));
            }

            Guid          orderId   = Guid.Parse(order.Id);
            ProcessedCart draftCart = null;

            var createOrderDraftParam = new CreateCartOrderDraftParam
            {
                CultureInfo = ComposerContext.CultureInfo,
                OrderId     = orderId,
                Scope       = order.ScopeId,
                CustomerId  = Guid.Parse(order.CustomerId)
            };

            try
            {
                draftCart = await OrderRepository.CreateCartOrderDraft(createOrderDraftParam).ConfigureAwait(false);
            }
            catch (ComposerException ex)
            {
                var ownedBySomeoneElseError   = ex.Errors?.FirstOrDefault(e => e.ErrorCode == Constants.ErrorCodes.IsOwnedBySomeoneElse);
                var ownedByRequestedUserError = ex.Errors?.FirstOrDefault(e => e.ErrorCode == Constants.ErrorCodes.IsOwnedByRequestedUser);
                if (ownedBySomeoneElseError != null)
                {
                    draftCart = await ChangeOwnership(order).ConfigureAwait(false);
                }
                else if (ownedByRequestedUserError != null)
                {
                    draftCart = await CartRepository.GetCartAsync(new GetCartParam
                    {
                        Scope       = order.ScopeId,
                        CartName    = order.Id.GetDraftCartName(),
                        CartType    = CartConfiguration.OrderDraftCartType,
                        CustomerId  = Guid.Parse(order.CustomerId),
                        CultureInfo = ComposerContext.CultureInfo
                    }).ConfigureAwait(false);
                }
                else
                {
                    throw;
                }
            }

            if (draftCart == null)
            {
                throw new InvalidOperationException("Expected draft cart, but received null.");
            }

            //Set Edit Mode
            ComposerContext.EditingCartName = draftCart.Name;

            return(draftCart);
        }
Example #9
0
 private bool ValidateOrder(Overture.ServiceModel.Orders.Order order)
 {
     return(order?.Cart?.Shipments != null &&
            !string.IsNullOrWhiteSpace(order.OrderStatus) &&
            Guid.TryParse(order.CustomerId, out Guid orderCustomerId) &&
            orderCustomerId != Guid.Empty &&
            orderCustomerId == ComposerContext.CustomerId &&
            !OrderHistoryConfiguration.CompletedOrderStatuses.Contains(order.OrderStatus));
 }
Example #10
0
 private Task DeleteCartDraft(Overture.ServiceModel.Orders.Order order)
 {
     return(OrderRepository.DeleteCartOrderDraft(new DeleteCartOrderDraftParam
     {
         CustomerId = Guid.Parse(order.CustomerId),
         Scope = order.ScopeId,
         OrderId = Guid.Parse(order.Id)
     }));
 }
Example #11
0
 private Task <ProcessedCart> ChangeOwnership(Overture.ServiceModel.Orders.Order order)
 {
     return(OrderRepository.ChangeOwnership(new ChangeOrderDraftOwnershipParam()
     {
         CultureName = ComposerContext.CultureInfo.Name,
         RevertPendingChanges = true,
         OrderId = Guid.Parse(order.Id),
         Scope = order.ScopeId,
         CustomerId = Guid.Parse(order.CustomerId)
     }));
 }
 protected virtual IEnumerable <Shipment> GetActiveShipments(Overture.ServiceModel.Orders.Order order)
 {
     if (order.OrderStatus.Equals(_orderStatusCanceled))
     {
         return(order.Cart.Shipments);
     }
     else
     {
         return(order.Cart.GetActiveShipments());
     }
 }
        protected virtual List <CouponViewModel> MapCoupons(Overture.ServiceModel.Orders.Order order, CultureInfo cultureInfo)
        {
            if (order?.Cart == null)
            {
                return(new List <CouponViewModel>());
            }

            var couponsViewModel = CartViewModelFactory.GetCouponsViewModel(order.Cart, cultureInfo, false);

            return(couponsViewModel != null ? couponsViewModel.ApplicableCoupons : new List <CouponViewModel>());
        }
Example #14
0
        public async Task CancelOrder(Overture.ServiceModel.Orders.Order order)
        {
            if (order == null)
            {
                throw new ArgumentNullException(nameof(order));
            }

            var isOrderCancelable = (await GetCancellationStatus(order).ConfigureAwait(false)).CanCancel;

            if (!isOrderCancelable)
            {
                throw new InvalidOperationException($"Order {order.Id} can't be cancelled");
            }

            var shipmentsTasks = order.Cart.Shipments.Select(shipment =>
                                                             OrderRepository.ChangeShipmentStatusAsync(new ChangeShipmentStatusParam
            {
                OrderId         = Guid.Parse(order.Id),
                ScopeId         = order.ScopeId,
                ShipmentId      = shipment.Id,
                Reason          = Constants.DefaultOrderCancellationReason,
                RequestedStatus = Constants.OrderStatus.Canceled
            }));

            await Task.WhenAll(shipmentsTasks).ConfigureAwait(false);

            var propertyBagShipment = new Dictionary <string, object>();

            propertyBagShipment.Add(Constants.RequestedOrderCancellationDatePropertyBagKey, DateTime.UtcNow);

            var shipmentFulfillmentMessagesTasks = order.Cart.Shipments
                                                   .Select(shipment =>
                                                           OrderRepository.AddShipmentFulfillmentMessagesAsync(new AddShipmentFulfillmentMessagesParam
            {
                OrderId           = Guid.Parse(order.Id),
                ScopeId           = order.ScopeId,
                ShipmentId        = shipment.Id,
                ExecutionMessages = new List <ExecutionMessage>()
                {
                    new ExecutionMessage()
                    {
                        Severity    = ExecutionMessageSeverity.Info,
                        MessageId   = order.Id,
                        PropertyBag = new PropertyBag(propertyBagShipment)
                    }
                }
            }));

            await Task.WhenAll(shipmentFulfillmentMessagesTasks).ConfigureAwait(false);
        }
        protected virtual async Task <OrderDetailViewModel> BuildOrderDetailViewModelAsync(
            Overture.ServiceModel.Orders.Order order,
            GetOrderParam getOrderParam)
        {
            var shipmentsNotes = await GetShipmentsNotes(order.Cart.Shipments, getOrderParam.Scope).ConfigureAwait(false);

            var orderChanges = await OrderRepository.GetOrderChangesAsync(new GetOrderChangesParam
            {
                OrderNumber = getOrderParam.OrderNumber,
                Scope       = getOrderParam.Scope
            }).ConfigureAwait(false);

            var orderStatuses = await LookupService.GetLookupDisplayNamesAsync(new GetLookupDisplayNamesParam
            {
                CultureInfo = getOrderParam.CultureInfo,
                LookupType  = LookupType.Order,
                LookupName  = "OrderStatus",
            }).ConfigureAwait(false);

            var shipmentStatuses = await LookupService.GetLookupDisplayNamesAsync(new GetLookupDisplayNamesParam
            {
                CultureInfo = getOrderParam.CultureInfo,
                LookupType  = LookupType.Order,
                LookupName  = "ShipmentStatus",
            }).ConfigureAwait(false);

            var productImageInfo = new ProductImageInfo
            {
                ImageUrls = await ImageService.GetImageUrlsAsync(order.Cart.GetLineItems()).ConfigureAwait(false)
            };

            var viewModel = OrderDetailsViewModelFactory.CreateViewModel(new CreateOrderDetailViewModelParam
            {
                Order            = order,
                OrderChanges     = orderChanges,
                OrderStatuses    = orderStatuses,
                ShipmentStatuses = shipmentStatuses,
                CultureInfo      = getOrderParam.CultureInfo,
                CountryCode      = getOrderParam.CountryCode,
                ProductImageInfo = productImageInfo,
                BaseUrl          = getOrderParam.BaseUrl,
                ShipmentsNotes   = shipmentsNotes
            });

            return(viewModel);
        }
Example #16
0
        protected virtual async Task <OrderDetailViewModel> BuildOrderDetailViewModelAsync(
            Overture.ServiceModel.Orders.Order order,
            GetOrderParam getOrderParam)
        {
            Helper.LineItemsHelper.PrepareGiftLineItems(order.Cart);

            var shipmentsNotes = await GetShipmentsNotes(order.Cart.Shipments, getOrderParam.Scope).ConfigureAwait(false);

            var orderChanges = await OrderRepository.GetOrderChangesAsync(new GetOrderChangesParam
            {
                OrderNumber = getOrderParam.OrderNumber,
                Scope       = getOrderParam.Scope
            }).ConfigureAwait(false);

            var orderCartDrafts = await GetOrderCartDrafts(getOrderParam.Scope, Guid.Parse(order.CustomerId), getOrderParam.CultureInfo).ConfigureAwait(false);

            var orderStatuses = await LookupService.GetLookupDisplayNamesAsync(new GetLookupDisplayNamesParam
            {
                CultureInfo = getOrderParam.CultureInfo,
                LookupType  = LookupType.Order,
                LookupName  = "OrderStatus",
            }).ConfigureAwait(false);

            var shipmentStatuses = await LookupService.GetLookupDisplayNamesAsync(new GetLookupDisplayNamesParam
            {
                CultureInfo = getOrderParam.CultureInfo,
                LookupType  = LookupType.Order,
                LookupName  = "ShipmentStatus",
            }).ConfigureAwait(false);

            var productImageInfo = new ProductImageInfo
            {
                ImageUrls = await ImageService.GetImageUrlsAsync(order.Cart.GetLineItems()).ConfigureAwait(false)
            };

            var viewModel = OrderDetailsViewModelFactory.CreateViewModel(new CreateOrderDetailViewModelParam
            {
                Order            = order,
                OrderChanges     = orderChanges,
                OrderStatuses    = orderStatuses,
                ShipmentStatuses = shipmentStatuses,
                CultureInfo      = getOrderParam.CultureInfo,
                CountryCode      = getOrderParam.CountryCode,
                ProductImageInfo = productImageInfo,
                BaseUrl          = getOrderParam.BaseUrl,
                ShipmentsNotes   = shipmentsNotes,
                OrderCartDrafts  = orderCartDrafts
            });

            viewModel.OrderInfos.IsOrderEditable = await EditingOrderProvider.CanEdit(order).ConfigureAwait(false);

            viewModel.OrderInfos.IsBeingEdited = EditingOrderProvider.IsBeingEdited(order);

            var orderCancellationStatus = await EditingOrderProvider.GetCancellationStatus(order).ConfigureAwait(false);

            viewModel.OrderInfos.IsOrderCancelable          = orderCancellationStatus.CanCancel;
            viewModel.OrderInfos.IsOrderPendingCancellation = orderCancellationStatus.CancellationPending;

            if (order.Cart.PropertyBag.TryGetValue("PickedItems", out var pickedItemsObject))
            {
                var pickedItemsList = ComposerJsonSerializer.Deserialize <List <PickedItemViewModel> >(pickedItemsObject.ToString());
                var shipment        = viewModel.Shipments.First();
                shipment.LineItems = await ProcessPickedLineItemsAsync(pickedItemsList, shipment.LineItems, getOrderParam.CultureInfo).ConfigureAwait(false);
            }
            ;

            return(viewModel);
        }
        protected virtual List <CompleteCheckoutLineItemViewModel> MapCompleteCheckoutLineItems(Overture.ServiceModel.Orders.Order order, CultureInfo cultureInfo)
        {
            var lineItems = order.Cart.GetLineItems().Select(li =>
            {
                var viewModel = ViewModelMapper.MapTo <CompleteCheckoutLineItemViewModel>(li, cultureInfo);

                var brandProperty = li.ProductSummary.Brand ?? string.Empty;

                var brand = string.IsNullOrWhiteSpace(brandProperty) ? string.Empty : LookupService.GetLookupDisplayNameAsync(new GetLookupDisplayNameParam
                {
                    Delimiter   = ", ",
                    LookupName  = "Brand",
                    LookupType  = LookupType.Product,
                    Value       = li.ProductSummary.Brand,
                    CultureInfo = cultureInfo
                }).Result;
                viewModel.Name       = li.ProductSummary.DisplayName;
                viewModel.BrandId    = brandProperty;
                viewModel.Brand      = brand;
                viewModel.CategoryId = li.ProductSummary.PrimaryParentCategoryId;
                viewModel.KeyVariantAttributesList = LineItemViewModelFactory.GetKeyVariantAttributes(new GetKeyVariantAttributesParam {
                    KvaValues        = li.KvaValues,
                    KvaDisplayValues = li.KvaDisplayValues
                }).ToList();

                return(viewModel);
            });

            return(lineItems.ToList());
        }
        protected virtual CompleteCheckoutViewModel MapOrderToCompleteCheckoutViewModel(Overture.ServiceModel.Orders.Order order, CultureInfo cultureInfo)
        {
            if (order == null)
            {
                return(null);
            }

            var completeCheckoutViewModel = new CompleteCheckoutViewModel
            {
                OrderNumber     = order.OrderNumber,
                CustomerEmail   = order.Cart.Customer.Email,
                Affiliation     = order.Cart.OrderLocation?.Name,
                Revenu          = order.Cart.Total,
                Tax             = order.Cart.TaxTotal,
                Shipping        = order.Cart.FulfillmentCost,
                ShippingOptions = order.Cart.Shipments?.FirstOrDefault()?.FulfillmentMethod.FulfillmentMethodType.ToString().ToLowerInvariant(),
                BillingCurrency = order.Cart.BillingCurrency,
                Coupons         = MapCoupons(order, cultureInfo),
                LineItems       = MapCompleteCheckoutLineItems(order, cultureInfo)
            };

            return(completeCheckoutViewModel);
        }
Example #19
0
 public virtual bool IsBeingEdited(Overture.ServiceModel.Orders.Order order)
 {
     return(order != null && IsEditMode() & ComposerContext.EditingCartName == order.Id.GetDraftCartName());
 }
Example #20
0
        protected virtual async Task <CompleteCheckoutViewModel> MapOrderToCompleteCheckoutViewModel(Overture.ServiceModel.Orders.Order order,
                                                                                                     CompleteCheckoutParam param)
        {
            if (order == null)
            {
                return(null);
            }

            var orderStatuses = await LookupService.GetLookupDisplayNamesAsync(new GetLookupDisplayNamesParam
            {
                CultureInfo = param.CultureInfo,
                LookupType  = LookupType.Order,
                LookupName  = "OrderStatus",
            }).ConfigureAwait(false);

            var productImageInfo = new ProductImageInfo
            {
                ImageUrls = await ImageService.GetImageUrlsAsync(order.Cart.GetLineItems()).ConfigureAwait(false)
            };

            var getVmOrderParam = new CreateOrderDetailViewModelParam {
                Order              = order,
                CultureInfo        = param.CultureInfo,
                OrderStatuses      = orderStatuses,
                OrderDetailBaseUrl = OrderUrlProvider.GetOrderDetailsBaseUrl(param.CultureInfo),
                BaseUrl            = param.BaseUrl,
                ProductImageInfo   = productImageInfo,
            };

            var orderViewModel = OrderDetailsViewModelFactory.CreateLightViewModel(getVmOrderParam);

            var completeCheckoutViewModel = new CompleteCheckoutViewModel
            {
                OrderNumber       = order.OrderNumber,
                Order             = orderViewModel,
                CustomerEmail     = order.Cart.Customer.Email,
                CustomerFirstName = order.Cart.Customer.FirstName,
                CustomerLastName  = order.Cart.Customer.LastName,
                Affiliation       = order.Cart.OrderLocation?.Name,
                Revenu            = order.Cart.Total,
                Tax             = order.Cart.TaxTotal,
                Shipping        = order.Cart.FulfillmentCost,
                ShippingOptions = order.Cart.Shipments?.FirstOrDefault()?.FulfillmentMethod.FulfillmentMethodType.ToString().ToLowerInvariant(),
                BillingCurrency = order.Cart.BillingCurrency,
                Coupons         = MapCoupons(order, param.CultureInfo),
                LineItems       = orderViewModel?.Shipments.FirstOrDefault()?.LineItems
            };

            return(completeCheckoutViewModel);
        }
Example #21
0
        public virtual async Task <Overture.ServiceModel.Orders.Order> SaveEditedOrderAsync(Overture.ServiceModel.Orders.Order order)
        {
            if (order == null)
            {
                throw new ArgumentNullException(nameof(order));
            }

            var isEditable = await CanEdit(order).ConfigureAwait(false);

            if (!isEditable)
            {
                await CancelEditOrderAsync(order).ConfigureAwait(false);

                throw new InvalidOperationException($"Cannot update edited order #${order.OrderNumber} as it can't be edited now.");
            }

            Overture.ServiceModel.Orders.Order updatedOrder;
            try
            {
                updatedOrder = await SaveEditedOrder(order).ConfigureAwait(false);
            }
            catch (ComposerException ex)
            {
                var ownedBySomeoneElseError = ex.Errors?.FirstOrDefault(e => e.ErrorCode == Constants.ErrorCodes.IsOwnedBySomeoneElse);
                if (ownedBySomeoneElseError != null)
                {
                    await ChangeOwnership(order).ConfigureAwait(false);

                    updatedOrder = await SaveEditedOrder(order).ConfigureAwait(false);
                }
                else
                {
                    throw;
                }
            }

            ClearEditMode();

            return(updatedOrder);
        }