public CreateOrderItemRequest(
     Order order,
     string odsCode,
     string catalogueItemId,
     CatalogueItemType catalogueItemType,
     string catalogueItemName,
     string provisioningTypeName,
     string cataloguePriceTypeName,
     string cataloguePriceUnitTierName,
     string cataloguePriceUnitDescription,
     string priceTimeUnitName,
     string currencyCode,
     int quantity,
     string estimationPeriodName,
     DateTime?deliveryDate,
     decimal?price)
 {
     Order                         = order ?? throw new ArgumentNullException(nameof(order));
     OdsCode                       = odsCode;
     CatalogueItemId               = catalogueItemId;
     CatalogueItemType             = catalogueItemType ?? throw new ArgumentNullException(nameof(catalogueItemType));
     CatalogueItemName             = catalogueItemName;
     ProvisioningTypeName          = provisioningTypeName;
     CataloguePriceTypeName        = cataloguePriceTypeName;
     CataloguePriceUnitTierName    = cataloguePriceUnitTierName;
     CataloguePriceUnitDescription = cataloguePriceUnitDescription;
     PriceTimeUnitName             = priceTimeUnitName;
     CurrencyCode                  = currencyCode;
     Quantity                      = quantity;
     EstimationPeriodName          = estimationPeriodName;
     DeliveryDate                  = deliveryDate;
     Price                         = price;
 }
コード例 #2
0
        public async Task GetList_WithItemType_PassesExpectedQuery()
        {
            GetSuppliersByNameQuery actualQuery = null;

            var mockMediator = new Mock <IMediator>();

            mockMediator
            .Setup(m => m.Send(It.IsNotNull <IRequest <IEnumerable <ISupplier> > >(), It.IsAny <CancellationToken>()))
            .Callback <IRequest <IEnumerable <ISupplier> >, CancellationToken>((q, _) => actualQuery = (GetSuppliersByNameQuery)q)
            .ReturnsAsync(Array.Empty <ISupplier>());

            const string            expectedName = "Supplier Name";
            const CatalogueItemType expectedCatalogueItemType = CatalogueItemType.AdditionalService;
            const PublishedStatus   expectedPublishedStatus   = PublishedStatus.Draft;

            var controller  = new SuppliersController(mockMediator.Object);
            var searchQuery = new SupplierSearchQueryModel
            {
                CatalogueItemType = expectedCatalogueItemType,
                Name = expectedName,
                SolutionPublicationStatus = expectedPublishedStatus,
            };

            await controller.GetList(searchQuery);

            var expectedQuery = new GetSuppliersByNameQuery(expectedName, expectedPublishedStatus, expectedCatalogueItemType);

            actualQuery.Should().BeEquivalentTo(expectedQuery);
        }
コード例 #3
0
        public static void Validate_DeliveryDateWithinMaxDeliveryDateOffsetInDays_SuccessIsTrue(
            Order order,
            CreateOrderItemModel model,
            CatalogueItemType itemType,
            ValidationSettings validationSettings)
        {
            model.ServiceRecipients.Should().NotBeNullOrEmpty();

            itemType.Should().NotBe(CatalogueItemType.AssociatedService);

            var serviceRecipients = model.ServiceRecipients.Select(_ =>
                                                                   new OrderItemRecipientModel {
                DeliveryDate = order.CommencementDate.Value.AddDays(validationSettings.MaxDeliveryDateOffsetInDays - 1)
            }).ToList();

            OrderItemValidator orderItemValidator = new OrderItemValidator(validationSettings);

            order.CommencementDate.Should().NotBeNull();

            var result = orderItemValidator.Validate(order, new CreateOrderItemModel {
                ServiceRecipients = serviceRecipients
            }, itemType);

            result.FailedValidations.Should().BeEmpty();
            result.Success.Should().BeTrue();
        }
コード例 #4
0
        public static CreateOrderItemRequest ToRequest(
            this CreateOrderItemModel model,
            Order order,
            CatalogueItemType catalogueItemType)
        {
            if (model is null)
            {
                throw new ArgumentNullException(nameof(model));
            }

            if (order is null)
            {
                throw new ArgumentNullException(nameof(order));
            }

            return(new CreateOrderItemRequest(
                       order,
                       model.ServiceRecipient?.OdsCode,
                       model.CatalogueSolutionId,
                       catalogueItemType,
                       model.CatalogueSolutionName,
                       model.ProvisioningType,
                       model.Type,
                       model.ItemUnitModel?.Name,
                       model.ItemUnitModel?.Description,
                       null,
                       model.CurrencyCode,
                       model.Quantity,
                       model.EstimationPeriod,
                       model.DeliveryDate,
                       model.Price));
        }
コード例 #5
0
        public static void CalculateTotalOwnershipCost_SingleOneOffOrRecurringOrderItem_ReturnsTotalOwnershipCost(
            CatalogueItemType catalogueItemType,
            ProvisioningType provisioningType,
            decimal price,
            int quantity,
            decimal totalOwnershipCost)
        {
            var orderItem = OrderItemBuilder
                            .Create()
                            .WithCatalogueItem(new CatalogueItem {
                CatalogueItemType = catalogueItemType
            })
                            .WithProvisioningType(provisioningType)
                            .WithPrice(price)
                            .WithRecipient(new OrderItemRecipient {
                Quantity = quantity
            })
                            .Build();

            var order = OrderBuilder
                        .Create()
                        .WithOrderItem(orderItem)
                        .Build();

            order.CalculateTotalOwnershipCost().Should().Be(totalOwnershipCost);
        }
コード例 #6
0
        public static async Task ListAsync_WithFilter_ReturnsExpectedResult(
            [Frozen] Mock <IOrderItemService> service,
            [Frozen] CallOffId callOffId,
            List <OrderItem> orderItems,
            Order order,
            OrderItemsController controller)
        {
            foreach (var orderItem in orderItems)
            {
                order.AddOrUpdateOrderItem(orderItem);
            }

            const CatalogueItemType catalogueItemType = CatalogueItemType.AdditionalService;

            service.Setup(o => o.GetOrder(callOffId)).ReturnsAsync(order);
            service.Setup(o => o.GetOrderItems(callOffId, catalogueItemType)).ReturnsAsync(
                orderItems.Where(i => i.CatalogueItem.CatalogueItemType == catalogueItemType).Select(i => i).ToList());

            var expectedResult = orderItems
                                 .Where(i => i.CatalogueItem.CatalogueItemType == catalogueItemType)
                                 .Select(i => new GetOrderItemModel(i));

            var response = await controller.ListAsync(callOffId, catalogueItemType);

            response.Value.Should().BeEquivalentTo(expectedResult);
        }
コード例 #7
0
        public static void Validate_DeliveryDateAfterMaxDeliveryDateOffsetInDays_SuccessIsFalse(
            Order order,
            CreateOrderItemModel model,
            CatalogueItemType itemType,
            ValidationSettings validationSettings)
        {
            model.ServiceRecipients.Should().NotBeNullOrEmpty();

            OrderItemValidator orderItemValidator = new OrderItemValidator(validationSettings);

            var serviceRecipients = model.ServiceRecipients.Select(_ =>
                                                                   new OrderItemRecipientModel {
                DeliveryDate = order.CommencementDate.Value.AddDays(validationSettings.MaxDeliveryDateOffsetInDays + 1)
            }).ToList();

            var result = orderItemValidator.Validate(order, new CreateOrderItemModel {
                ServiceRecipients = serviceRecipients
            }, itemType);

            result.FailedValidations.Should().NotBeEmpty();

            foreach ((_, ValidationResult validationResult) in result.FailedValidations)
            {
                var errorDetails = validationResult.Errors.SingleOrDefault();
                errorDetails.Should().NotBeNull();
                errorDetails.Field.Should().Be("DeliveryDate");
                errorDetails.Id.Should().Be("DeliveryDateOutsideDeliveryWindow");
            }

            result.Success.Should().BeFalse();
        }
コード例 #8
0
 public static TimeUnit?InferEstimationPeriod(this CatalogueItemType itemType, ProvisioningType provisioningType, TimeUnit?estimationPeriod)
 {
     return(itemType switch
     {
         CatalogueItemType.AssociatedService => provisioningType == ProvisioningType.OnDemand
             ? provisioningType.InferEstimationPeriod(estimationPeriod)
             : null,
         _ => provisioningType.InferEstimationPeriod(estimationPeriod),
     });
コード例 #9
0
 private static OrderItem CreateOrderItem(CatalogueItemType catalogueItemType, ProvisioningType provisioningType)
 {
     return(OrderItemBuilder
            .Create()
            .WithCatalogueItem(new CatalogueItem {
         CatalogueItemType = catalogueItemType
     })
            .WithProvisioningType(provisioningType)
            .Build());
 }
コード例 #10
0
        public static void Validate_NullCommencementDate_ThrowsArgumentNullException(
            Order order,
            CreateOrderItemModel model,
            CatalogueItemType itemType,
            OrderItemValidator orderItemValidator)
        {
            order.CommencementDate = null;

            Assert.Throws <ArgumentNullException>(() => _ = orderItemValidator.Validate(order, model, itemType));
        }
コード例 #11
0
        public static void InferEstimationPeriod_ReturnsExpectedEstimationPeriod(
            CatalogueItemType catalogueItemType,
            ProvisioningType provisioningType,
            TimeUnit?estimationPeriod,
            TimeUnit?expectedEstimationPeriod)
        {
            var actual = catalogueItemType.InferEstimationPeriod(provisioningType, estimationPeriod);

            actual.Should().Be(expectedEstimationPeriod);
        }
コード例 #12
0
        public static async Task GetOrderItems_InvalidCallOffId_ReturnsNull(
            [Frozen] ApplicationDbContext context,
            CallOffId callOffId,
            CatalogueItemType catalogueItemType,
            OrderItemService service)
        {
            (await context.Order.AnyAsync(o => o.CallOffId == callOffId)).Should().BeFalse();
            var result = await service.GetOrderItems(callOffId, catalogueItemType);

            result.Should().BeNull();
        }
コード例 #13
0
        public static void MarkOrderSectionAsViewed_MarksExpectedSection(
            CatalogueItemType itemType,
            Func <Order, bool> sectionViewed)
        {
            var order = OrderBuilder.Create().Build();

            sectionViewed(order).Should().BeFalse();

            itemType.MarkOrderSectionAsViewed(order);

            sectionViewed(order).Should().BeTrue();
        }
        public void List_ReturnsExpectedList()
        {
            var actual = CatalogueItemType.List();

            var expected = new List <CatalogueItemType>
            {
                CatalogueItemType.Solution,
                CatalogueItemType.AdditionalService,
                CatalogueItemType.AssociatedService
            };

            actual.Should().BeEquivalentTo(expected);
        }
コード例 #15
0
 private OrderItemBuilder()
 {
     _odsCode            = "ODS1";
     _catalogueItemId    = "1000-001";
     _catalogueItemType  = CatalogueItemType.Solution;
     _catalogueItemName  = Guid.NewGuid().ToString();
     _provisioningType   = ProvisioningType.Patient;
     _cataloguePriceType = CataloguePriceType.Flat;
     _cataloguePriceUnit = CataloguePriceUnit.Create("patients", "per patient");
     _priceTimeUnit      = null;
     _currencyCode       = "GBP";
     _quantity           = 10;
     _estimationPeriod   = TimeUnit.PerYear;
     _deliveryDate       = DateTime.UtcNow;
     _price = 2.000m;
 }
        public static async Task <CatalogueItemEntity> CreateCatalogueItemEntity(
            string catalogueItemId,
            string supplierId,
            CatalogueItemType catalogueItemType,
            PublishedStatus publishedStatus = PublishedStatus.Published)
        {
            var catalogueItem = CatalogueItemEntityBuilder
                                .Create()
                                .WithCatalogueItemId(catalogueItemId)
                                .WithSupplierId(supplierId)
                                .WithCatalogueItemTypeId((int)catalogueItemType)
                                .WithPublishedStatusId((int)publishedStatus)
                                .Build();

            await catalogueItem.InsertAsync();

            return(catalogueItem);
        }
コード例 #17
0
 private CreateOrderItemRequestBuilder()
 {
     _order                         = OrderBuilder.Create().Build();
     _odsCode                       = "ODS2";
     _catalogueItemId               = "10001-001";
     _catalogueItemType             = CatalogueItemType.AssociatedService;
     _catalogueItemName             = "Some catalogue item name";
     _provisioningTypeName          = "Declarative";
     _cataloguePriceTypeName        = "Flat";
     _cataloguePriceUnitTierName    = "sms";
     _cataloguePriceUnitDescription = "per sms";
     _priceTimeUnitName             = "month";
     _currencyCode                  = "EUR";
     _quantity                      = 10;
     _estimationPeriodName          = "year";
     _deliveryDate                  = DateTime.UtcNow;
     _price                         = 2;
 }
コード例 #18
0
        public static void AddOrderItem_OrderItem_CatalogueItemType_AssociatedServicesViewedMatchExpectedValue(
            CatalogueItemType catalogueItemType,
            bool expectedInput)
        {
            var order = OrderBuilder
                        .Create()
                        .WithAdditionalServicesViewed(false)
                        .Build();

            var orderItem = OrderItemBuilder
                            .Create()
                            .WithCatalogueItem(new CatalogueItem {
                CatalogueItemType = catalogueItemType
            })
                            .Build();

            order.AddOrUpdateOrderItem(orderItem);

            order.Progress.AdditionalServicesViewed.Should().Be(expectedInput);
        }
コード例 #19
0
        private static IEnumerable <object[]> AdditionalServiceSolutionData(CatalogueItemType itemType)
        {
            yield return(new object[] { itemType, ProvisioningType.OnDemand, null, null });

            yield return(new object[] { itemType, ProvisioningType.OnDemand, TimeUnit.PerMonth, TimeUnit.PerMonth });

            yield return(new object[] { itemType, ProvisioningType.OnDemand, TimeUnit.PerYear, TimeUnit.PerYear });

            yield return(new object[] { itemType, ProvisioningType.Patient, null, TimeUnit.PerMonth });

            yield return(new object[] { itemType, ProvisioningType.Patient, TimeUnit.PerMonth, TimeUnit.PerMonth });

            yield return(new object[] { itemType, ProvisioningType.Patient, TimeUnit.PerYear, TimeUnit.PerMonth });

            yield return(new object[] { itemType, ProvisioningType.Declarative, null, TimeUnit.PerYear });

            yield return(new object[] { itemType, ProvisioningType.Declarative, TimeUnit.PerMonth, TimeUnit.PerYear });

            yield return(new object[] { itemType, ProvisioningType.Declarative, TimeUnit.PerYear, TimeUnit.PerYear });
        }
        public static async Task <OrderItem> CreateOrderItem(
            Order order,
            CatalogueItemType catalogueItemType,
            CataloguePriceType cataloguePriceType,
            ProvisioningType provisioningType,
            OrderingDbContext context,
            string connectionString,
            TimeUnit timeUnit = TimeUnit.PerYear)
        {
            var solution = await SupplierInfo.GetPublishedCatalogueItemsNoTieredAsync(connectionString, order.Supplier.Id, catalogueItemType);

            var selectedItem = RandomInformation.GetRandomItem(solution);

            var catalogueItem = await context.FindAsync <CatalogueItem>(CatalogueItemId.ParseExact(selectedItem.CatalogueItemId))
                                ?? selectedItem.ToDomain();

            var catalogueItemPricingUnit = await GetPricingUnitAsync(provisioningType, connectionString);

            var pricingUnit = await context.FindAsync <PricingUnit>(catalogueItemPricingUnit.Name) ?? catalogueItemPricingUnit;

            var orderItem = new OrderItemBuilder(order.Id)
                            .WithCatalogueItem(catalogueItem)
                            .WithCataloguePriceType(cataloguePriceType)
                            .WithCurrencyCode()
                            .WithDefaultDeliveryDate(DateTime.Today)
                            .WithPrice(0.01M)
                            .WithPricingTimeUnit(timeUnit)
                            .WithProvisioningType(provisioningType)
                            .WithPricingUnit(pricingUnit)
                            .WithEstimationPeriod(timeUnit);

            if (provisioningType == ProvisioningType.OnDemand)
            {
                orderItem.WithEstimationPeriod(timeUnit);
            }

            return(orderItem.Build());
        }
コード例 #21
0
 private OrderItemEntityBuilder(
     string orderId,
     string odsCode,
     string catalogueItemId,
     CatalogueItemType catalogueItemType,
     string catalogueItemName,
     DateTime?deliveryDate,
     int quantity,
     TimeUnit?estimationPeriod,
     ProvisioningType provisioningType,
     CataloguePriceType cataloguePriceType,
     string currencyCode,
     TimeUnit?timeUnit,
     string pricingUnitTierName,
     string pricingUnitDescription,
     decimal?price,
     DateTime created,
     DateTime lastUpdated)
 {
     _orderId                = orderId;
     _odsCode                = odsCode;
     _catalogueItemId        = catalogueItemId;
     _catalogueItemType      = catalogueItemType;
     _catalogueItemName      = catalogueItemName;
     _deliveryDate           = deliveryDate;
     _quantity               = quantity;
     _estimationPeriod       = estimationPeriod;
     _provisioningType       = provisioningType;
     _cataloguePriceType     = cataloguePriceType;
     _currencyCode           = currencyCode;
     _timeUnit               = timeUnit;
     _pricingUnitTierName    = pricingUnitTierName;
     _pricingUnitDescription = pricingUnitDescription;
     _price       = price;
     _created     = created;
     _lastUpdated = lastUpdated;
 }
コード例 #22
0
        private async Task <CatalogueItem> AddOrUpdateCatalogueItem(
            CatalogueItemId catalogueItemId,
            CreateOrderItemModel model,
            CatalogueItemType catalogueItemType)
        {
            CatalogueItem parentCatalogueItem = null;
            var           catalogueSolutionId = model.CatalogueSolutionId;

            if (catalogueSolutionId is not null)
            {
                parentCatalogueItem = await context.FindAsync <CatalogueItem>(CatalogueItemId.Parse(catalogueSolutionId).Id);
            }

            var catalogueItem = await context.FindAsync <CatalogueItem>(catalogueItemId) ?? new CatalogueItem
            {
                Id = catalogueItemId,
                CatalogueItemType = catalogueItemType,
            };

            catalogueItem.Name = model.CatalogueItemName;
            catalogueItem.ParentCatalogueItemId = parentCatalogueItem?.Id;

            return(catalogueItem);
        }
 public async Task ByNameAsync_ReturnsExpectedValues()
 {
     const string            supplierName   = "Supplier";
     const PublishedStatus   solutionStatus = PublishedStatus.Published;
     const CatalogueItemType itemType       = CatalogueItemType.Solution;
コード例 #24
0
        public static void DisplayName_ReturnsExpectedName(CatalogueItemType itemType, string expectedName)
        {
            var displayName = itemType.DisplayName();

            displayName.Should().Be(expectedName);
        }
        public void FromId_UnknownCatalogueItemTypeId_ReturnsNull()
        {
            var actual = CatalogueItemType.FromId(10);

            actual.Should().BeNull();
        }
        public void FromId_CatalogueItemTypeId_ReturnsExpectedType()
        {
            var actual = CatalogueItemType.FromId(1);

            actual.Should().Be(CatalogueItemType.Solution);
        }
コード例 #27
0
        public void Configure(EntityTypeBuilder <OrderItem> builder)
        {
            if (builder is null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            builder.HasKey(orderItem => orderItem.OrderItemId);

            builder.Property(orderItem => orderItem.OrderItemId)
            .HasColumnName(nameof(OrderItem.OrderItemId))
            .IsRequired();

            builder.Property("OrderId")
            .HasColumnName("OrderId")
            .IsRequired();

            builder.Property(orderItem => orderItem.CatalogueItemId)
            .HasColumnName(nameof(OrderItem.CatalogueItemId))
            .IsRequired();

            builder
            .Property(orderItem => orderItem.CatalogueItemType)
            .HasConversion(input => input.Id, output => CatalogueItemType.FromId(output))
            .HasColumnName("CatalogueItemTypeId");

            builder.Property(orderItem => orderItem.CatalogueItemName)
            .HasColumnName(nameof(OrderItem.CatalogueItemName))
            .IsRequired();

            builder.Property(orderItem => orderItem.OdsCode)
            .HasColumnName(nameof(OrderItem.OdsCode));

            builder
            .Property(orderItem => orderItem.ProvisioningType)
            .HasConversion(input => input.Id, output => ProvisioningType.FromId(output))
            .HasColumnName("ProvisioningTypeId");

            builder
            .Property(orderItem => orderItem.CataloguePriceType)
            .HasConversion(input => input.Id, output => CataloguePriceType.FromId(output))
            .HasColumnName("CataloguePriceTypeId");

            builder.OwnsOne(orderItem => orderItem.CataloguePriceUnit, navigationBuilder =>
            {
                navigationBuilder.Property(cataloguePriceUnit => cataloguePriceUnit.TierName)
                .HasColumnName("PricingUnitTierName");

                navigationBuilder.Property(cataloguePriceUnit => cataloguePriceUnit.Description)
                .HasColumnName("PricingUnitDescription");
            });

            builder
            .Property(orderItem => orderItem.PriceTimeUnit)
            .HasConversion(input => input.Id, output => TimeUnit.FromId(output))
            .HasColumnName("TimeUnitId");

            builder.Property(orderItem => orderItem.CurrencyCode)
            .HasColumnName(nameof(OrderItem.CurrencyCode))
            .IsRequired();

            builder.Property(orderItem => orderItem.Quantity)
            .HasColumnName(nameof(OrderItem.Quantity))
            .IsRequired();

            builder
            .Property(orderItem => orderItem.EstimationPeriod)
            .HasConversion(input => input.Id, output => TimeUnit.FromId(output))
            .HasColumnName("EstimationPeriodId");

            builder.Property(orderItem => orderItem.DeliveryDate)
            .HasColumnName(nameof(OrderItem.DeliveryDate));

            builder.Property(orderItem => orderItem.Price)
            .HasColumnName(nameof(OrderItem.Price))
            .HasColumnType("decimal(18, 3)");
        }
コード例 #28
0
 public OrderItemBuilder WithCatalogueItemType(CatalogueItemType catalogueItemType)
 {
     _catalogueItemType = catalogueItemType;
     return(this);
 }
コード例 #29
0
 public static string DisplayName(this CatalogueItemType itemType) => itemType.AsString(EnumFormat.DisplayName);
コード例 #30
0
        public static void CostType_DeterminesTheCostType_ReturnsCorrectCostType(CatalogueItemType catalogueItemType, ProvisioningType provisioningType, CostType costType)
        {
            var orderItem = CreateOrderItem(catalogueItemType, provisioningType);

            orderItem.CostType.Should().Be(costType);
        }