示例#1
0
        /// <summary>
        /// Removes a customer subscription.
        /// </summary>
        /// <param name="customerSubscriptionToRemove">The customer subscription to remove.</param>
        /// <returns>A task.</returns>
        public async Task DeleteAsync(CustomerSubscriptionEntity customerSubscriptionToRemove)
        {
            customerSubscriptionToRemove.AssertNotNull(nameof(customerSubscriptionToRemove));

            var customerSubscriptionsTable = await this.ApplicationDomain.AzureStorageService.GetCustomerSubscriptionsTableAsync();

            var deletionResult = await customerSubscriptionsTable.ExecuteAsync(TableOperation.Delete(new CustomerSubscriptionTableEntity(customerSubscriptionToRemove.CustomerId, customerSubscriptionToRemove.SubscriptionId)
            {
                ETag = "*"
            }));

            deletionResult.HttpStatusCode.AssertHttpResponseSuccess(ErrorCode.PersistenceFailure, "Failed to remove customer subscription", deletionResult.Result);
        }
        /// <summary>
        /// Retrieves a customer subscription from persistence.
        /// </summary>
        /// <param name="subscriptionId">The subscription ID.</param>
        /// <param name="customerId">The customer ID.</param>
        /// <returns>The matching subscription.</returns>
        private static async Task <CustomerSubscriptionEntity> GetSubscriptionAsync(string subscriptionId, string customerId)
        {
            // grab the customer subscription from our store
            IEnumerable <CustomerSubscriptionEntity> customerSubscriptions = await ApplicationDomain.Instance.CustomerSubscriptionsRepository.RetrieveAsync(customerId).ConfigureAwait(false);

            CustomerSubscriptionEntity subscriptionToAugment = customerSubscriptions.FirstOrDefault(subscription => subscription.SubscriptionId == subscriptionId);

            if (subscriptionToAugment == null)
            {
                throw new PartnerDomainException(ErrorCode.SubscriptionNotFound);
            }

            return(subscriptionToAugment);
        }
示例#3
0
        /// <summary>
        /// Adds a new customer subscription.
        /// </summary>
        /// <param name="newCustomerSubscription">The new subscription information.</param>
        /// <returns>The just added customer subscription.</returns>
        public async Task <CustomerSubscriptionEntity> AddAsync(CustomerSubscriptionEntity newCustomerSubscription)
        {
            newCustomerSubscription.AssertNotNull(nameof(newCustomerSubscription));

            CustomerSubscriptionTableEntity customerSubscriptionTableEntity = new CustomerSubscriptionTableEntity(newCustomerSubscription.CustomerId, newCustomerSubscription.SubscriptionId)
            {
                PartnerOfferId = newCustomerSubscription.PartnerOfferId,
                ExpiryDate     = newCustomerSubscription.ExpiryDate
            };

            var customerSubscriptionsTable = await this.ApplicationDomain.AzureStorageService.GetCustomerSubscriptionsTableAsync();

            var insertionResult = await customerSubscriptionsTable.ExecuteAsync(TableOperation.Insert(customerSubscriptionTableEntity));

            insertionResult.HttpStatusCode.AssertHttpResponseSuccess(ErrorCode.PersistenceFailure, "Failed to add customer subscription", insertionResult.Result);

            return(newCustomerSubscription);
        }
示例#4
0
        /// <summary>
        /// Updates a customer subscription.
        /// </summary>
        /// <param name="customerSubscriptionUpdates">The customer subscription updates.</param>
        /// <returns>The updated customer subscription.</returns>
        public async Task <CustomerSubscriptionEntity> UpdateAsync(CustomerSubscriptionEntity customerSubscriptionUpdates)
        {
            customerSubscriptionUpdates.AssertNotNull(nameof(customerSubscriptionUpdates));

            var updateSubscriptionOperation = TableOperation.Replace(new CustomerSubscriptionTableEntity(customerSubscriptionUpdates.CustomerId, customerSubscriptionUpdates.SubscriptionId)
            {
                ExpiryDate     = customerSubscriptionUpdates.ExpiryDate,
                PartnerOfferId = customerSubscriptionUpdates.PartnerOfferId,
                ETag           = "*"
            });

            var customerSubscriptionsTable = await this.ApplicationDomain.AzureStorageService.GetCustomerSubscriptionsTableAsync();

            var updateResult = await customerSubscriptionsTable.ExecuteAsync(updateSubscriptionOperation);

            updateResult.HttpStatusCode.AssertHttpResponseSuccess(ErrorCode.PersistenceFailure, "Failed to update customer subscription", updateResult.Result);

            return(customerSubscriptionUpdates);
        }
        /// <summary>
        /// Normalizes an order to renew a subscription.
        /// </summary>
        /// <returns>Normalized order.</returns>
        public async Task <OrderViewModel> NormalizeRenewSubscriptionOrderAsync()
        {
            OrderViewModel order = Order;

            order.CustomerId.AssertNotEmpty(nameof(order.CustomerId));
            if (order.OperationType != CommerceOperationType.Renewal)
            {
                throw new PartnerDomainException(ErrorCode.InvalidInput, Resources.InvalidOperationForOrderMessage).AddDetail("Field", "OperationType");
            }

            // create result order object prefilling it with operation type & customer id.
            OrderViewModel orderResult = new OrderViewModel()
            {
                CustomerId    = order.CustomerId,
                OrderId       = order.OrderId,
                OperationType = order.OperationType
            };

            order.Subscriptions.AssertNotNull(nameof(order.Subscriptions));
            List <OrderSubscriptionItemViewModel> orderSubscriptions = order.Subscriptions.ToList();

            if (orderSubscriptions.Count != 1)
            {
                throw new PartnerDomainException(ErrorCode.InvalidInput, Resources.MoreThanOneSubscriptionUpdateErrorMessage);
            }

            string subscriptionId = orderSubscriptions.First().SubscriptionId;

            subscriptionId.AssertNotEmpty(nameof(subscriptionId)); // is Required for the commerce operation.

            // grab the customer subscription from our store
            CustomerSubscriptionEntity subscriptionToAugment = await GetSubscriptionAsync(subscriptionId, order.CustomerId).ConfigureAwait(false);

            // retrieve the partner offer this subscription relates to, we need to know the current price
            PartnerOffer partnerOffer = await ApplicationDomain.Instance.OffersRepository.RetrieveAsync(subscriptionToAugment.PartnerOfferId).ConfigureAwait(false);

            if (partnerOffer.IsInactive)
            {
                // renewing deleted offers is prohibited
                throw new PartnerDomainException(ErrorCode.PurchaseDeletedOfferNotAllowed).AddDetail("Id", partnerOffer.Id);
            }

            // retrieve the subscription from Partner Center
            Subscriptions.ISubscription subscriptionOperations = ApplicationDomain.Instance.PartnerCenterClient.Customers.ById(order.CustomerId).Subscriptions.ById(subscriptionId);
            PartnerCenter.Models.Subscriptions.Subscription partnerCenterSubscription = await subscriptionOperations.GetAsync().ConfigureAwait(false);

            List <OrderSubscriptionItemViewModel> resultOrderSubscriptions = new List <OrderSubscriptionItemViewModel>
            {
                new OrderSubscriptionItemViewModel()
                {
                    OfferId                = subscriptionId,
                    SubscriptionId         = subscriptionId,
                    PartnerOfferId         = subscriptionToAugment.PartnerOfferId,
                    SubscriptionExpiryDate = subscriptionToAugment.ExpiryDate,
                    Quantity               = partnerCenterSubscription.Quantity,
                    SeatPrice              = partnerOffer.Price,
                    SubscriptionName       = partnerOffer.Title
                }
            };

            orderResult.Subscriptions = resultOrderSubscriptions;

            return(orderResult);
        }
        /// <summary>
        /// Normalizes an order to add seats to a subscription.
        /// </summary>
        /// <returns>Normalized order.</returns>
        public async Task <OrderViewModel> NormalizePurchaseAdditionalSeatsOrderAsync()
        {
            OrderViewModel order = Order;

            order.CustomerId.AssertNotEmpty(nameof(order.CustomerId));

            if (order.OperationType != CommerceOperationType.AdditionalSeatsPurchase)
            {
                throw new PartnerDomainException(ErrorCode.InvalidInput, Resources.InvalidOperationForOrderMessage).AddDetail("Field", "OperationType");
            }

            // create result order object prefilling it with operation type & customer id.
            OrderViewModel orderResult = new OrderViewModel()
            {
                CustomerId    = order.CustomerId,
                OrderId       = order.OrderId,
                OperationType = order.OperationType
            };

            order.Subscriptions.AssertNotNull(nameof(order.Subscriptions));
            List <OrderSubscriptionItemViewModel> orderSubscriptions = order.Subscriptions.ToList();

            if (orderSubscriptions.Count != 1)
            {
                throw new PartnerDomainException(ErrorCode.InvalidInput).AddDetail("ErrorMessage", Resources.MoreThanOneSubscriptionUpdateErrorMessage);
            }

            string subscriptionId  = orderSubscriptions.First().SubscriptionId;
            int    seatsToPurchase = orderSubscriptions.First().Quantity;

            subscriptionId.AssertNotEmpty(nameof(subscriptionId)); // is Required for the commerce operation.
            seatsToPurchase.AssertPositive("seatsToPurchase");

            // grab the customer subscription from our store
            CustomerSubscriptionEntity subscriptionToAugment = await GetSubscriptionAsync(subscriptionId, order.CustomerId).ConfigureAwait(false);

            // retrieve the partner offer this subscription relates to, we need to know the current price
            PartnerOffer partnerOffer = await ApplicationDomain.Instance.OffersRepository.RetrieveAsync(subscriptionToAugment.PartnerOfferId).ConfigureAwait(false);

            if (partnerOffer.IsInactive)
            {
                // renewing deleted offers is prohibited
                throw new PartnerDomainException(ErrorCode.PurchaseDeletedOfferNotAllowed).AddDetail("Id", partnerOffer.Id);
            }

            // retrieve the subscription from Partner Center
            Subscriptions.ISubscription subscriptionOperations = ApplicationDomain.Instance.PartnerCenterClient.Customers.ById(order.CustomerId).Subscriptions.ById(subscriptionId);

            // if subscription expiry date.Date is less than today's UTC date then subcription has expired.
            if (subscriptionToAugment.ExpiryDate.Date < DateTime.UtcNow.Date)
            {
                // this subscription has already expired, don't permit adding seats until the subscription is renewed
                throw new PartnerDomainException(ErrorCode.SubscriptionExpired);
            }

            decimal proratedSeatCharge = Math.Round(CommerceOperations.CalculateProratedSeatCharge(subscriptionToAugment.ExpiryDate, partnerOffer.Price), Resources.Culture.NumberFormat.CurrencyDecimalDigits);
            decimal totalCharge        = Math.Round(proratedSeatCharge * seatsToPurchase, Resources.Culture.NumberFormat.CurrencyDecimalDigits);

            List <OrderSubscriptionItemViewModel> resultOrderSubscriptions = new List <OrderSubscriptionItemViewModel>
            {
                new OrderSubscriptionItemViewModel()
                {
                    OfferId                = subscriptionId,
                    SubscriptionId         = subscriptionId,
                    PartnerOfferId         = subscriptionToAugment.PartnerOfferId,
                    SubscriptionExpiryDate = subscriptionToAugment.ExpiryDate,
                    Quantity               = seatsToPurchase,
                    SeatPrice              = proratedSeatCharge,
                    SubscriptionName       = partnerOffer.Title
                }
            };

            orderResult.Subscriptions = resultOrderSubscriptions;

            return(orderResult);
        }