/// <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); }
/// <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); }
/// <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); }