Ejemplo n.º 1
0
        /// <summary>
        /// Gets the summary of subscriptions for a portal customer.
        /// </summary>
        /// <param name="customerId">The customer Id.</param>
        /// <returns>Subscription Summary.</returns>
        private async Task <SubscriptionsSummary> GetSubscriptionSummaryAsync(string customerId)
        {
            DateTime startTime = DateTime.Now;
            IEnumerable <CustomerSubscriptionEntity> customerSubscriptions = await ApplicationDomain.Instance.CustomerSubscriptionsRepository.RetrieveAsync(customerId).ConfigureAwait(false);

            IEnumerable <CustomerPurchaseEntity> customerSubscriptionsHistory = await ApplicationDomain.Instance.CustomerPurchasesRepository.RetrieveAsync(customerId).ConfigureAwait(false);

            IEnumerable <PartnerOffer> allPartnerOffers = await ApplicationDomain.Instance.OffersRepository.RetrieveAsync().ConfigureAwait(false);

            IEnumerable <MicrosoftOffer> currentMicrosoftOffers = await ApplicationDomain.Instance.OffersRepository.RetrieveMicrosoftOffersAsync().ConfigureAwait(false);

            // start building the summary.
            decimal summaryTotal = 0;

            // format all responses to client using portal locale.
            CultureInfo responseCulture = new CultureInfo(ApplicationDomain.Instance.PortalLocalization.Locale);
            List <SubscriptionViewModel> customerSubscriptionsView = new List <SubscriptionViewModel>();

            // iterate through and build the list of customer's subscriptions.
            foreach (CustomerSubscriptionEntity subscription in customerSubscriptions)
            {
                decimal subscriptionTotal = 0;
                int     licenseTotal      = 0;
                List <SubscriptionHistory> historyItems = new List <SubscriptionHistory>();

                // collect the list of history items for this subcription.
                IOrderedEnumerable <CustomerPurchaseEntity> subscriptionHistoryList = customerSubscriptionsHistory
                                                                                      .Where(historyItem => historyItem.SubscriptionId == subscription.SubscriptionId)
                                                                                      .OrderBy(historyItem => historyItem.TransactionDate);

                // iterate through and build the SubsriptionHistory for this subscription.
                foreach (CustomerPurchaseEntity historyItem in subscriptionHistoryList)
                {
                    decimal orderTotal = Math.Round(historyItem.SeatPrice * historyItem.SeatsBought, responseCulture.NumberFormat.CurrencyDecimalDigits);
                    historyItems.Add(new SubscriptionHistory()
                    {
                        OrderTotal    = orderTotal.ToString("C", responseCulture),                                // Currency format.
                        PricePerSeat  = historyItem.SeatPrice.ToString("C", responseCulture),                     // Currency format.
                        SeatsBought   = historyItem.SeatsBought.ToString("G", responseCulture),                   // General format.
                        OrderDate     = historyItem.TransactionDate.ToLocalTime().ToString("d", responseCulture), // Short date format.
                        OperationType = GetOperationType(historyItem.PurchaseType)                                // Localized Operation type string.
                    });

                    // Increment the subscription total.
                    licenseTotal += historyItem.SeatsBought;

                    // Increment the subscription total.
                    subscriptionTotal += orderTotal;
                }

                PartnerOffer partnerOfferItem  = allPartnerOffers.FirstOrDefault(offer => offer.Id == subscription.PartnerOfferId);
                string       subscriptionTitle = partnerOfferItem.Title;
                string       portalOfferId     = partnerOfferItem.Id;
                decimal      portalOfferPrice  = partnerOfferItem.Price;

                DateTime subscriptionExpiryDate = subscription.ExpiryDate.ToUniversalTime();
                int      remainingDays          = (subscriptionExpiryDate.Date - DateTime.UtcNow.Date).Days;
                bool     isRenewable            = remainingDays <= 30;
                bool     isEditable             = DateTime.UtcNow.Date <= subscriptionExpiryDate.Date;

                // TODO :: Handle Microsoft offer being pulled back due to EOL.

                // Temporarily mark this partnerOffer item as inactive and dont allow store front customer to manage this subscription.
                MicrosoftOffer alignedMicrosoftOffer = currentMicrosoftOffers.FirstOrDefault(offer => offer.Offer.Id == partnerOfferItem.MicrosoftOfferId);
                if (alignedMicrosoftOffer == null)
                {
                    partnerOfferItem.IsInactive = true;
                }

                if (partnerOfferItem.IsInactive)
                {
                    // in case the offer is inactive (marked for deletion) then dont allow renewals or editing on this subscription tied to this offer.
                    isRenewable = false;
                    isEditable  = false;
                }

                // Compute the pro rated price per seat for this subcription & return for client side processing during updates.
                decimal proratedPerSeatPrice = Math.Round(CommerceOperations.CalculateProratedSeatCharge(subscription.ExpiryDate, portalOfferPrice), responseCulture.NumberFormat.CurrencyDecimalDigits);

                SubscriptionViewModel subscriptionItem = new SubscriptionViewModel()
                {
                    SubscriptionId            = subscription.SubscriptionId,
                    FriendlyName              = subscriptionTitle,
                    PortalOfferId             = portalOfferId,
                    PortalOfferPrice          = portalOfferPrice.ToString("C", responseCulture),
                    IsRenewable               = isRenewable,                                                // IsRenewable is true if subscription is going to expire in 30 days.
                    IsEditable                = isEditable,                                                 // IsEditable is true if today is lesser or equal to subscription expiry date.
                    LicensesTotal             = licenseTotal.ToString("G", responseCulture),                // General format.
                    SubscriptionTotal         = subscriptionTotal.ToString("C", responseCulture),           // Currency format.
                    SubscriptionExpiryDate    = subscriptionExpiryDate.Date.ToString("d", responseCulture), // Short date format.
                    SubscriptionOrderHistory  = historyItems,
                    SubscriptionProRatedPrice = proratedPerSeatPrice
                };

                // add this subcription to the customer's subscription list.
                customerSubscriptionsView.Add(subscriptionItem);

                // Increment the summary total.
                summaryTotal += subscriptionTotal;
            }

            // Capture the request for the customer summary for analysis.
            Dictionary <string, string> eventProperties = new Dictionary <string, string> {
                { "CustomerId", customerId }
            };

            // Track the event measurements for analysis.
            Dictionary <string, double> eventMetrics = new Dictionary <string, double> {
                { "ElapsedMilliseconds", DateTime.Now.Subtract(startTime).TotalMilliseconds }, { "NumberOfSubscriptions", customerSubscriptionsView.Count }
            };

            ApplicationDomain.Instance.TelemetryService.Provider.TrackEvent("GetSubscriptionSummaryAsync", eventProperties, eventMetrics);

            // Sort List of subscriptions based on portal offer name.
            return(new SubscriptionsSummary()
            {
                Subscriptions = customerSubscriptionsView.OrderBy(subscriptionItem => subscriptionItem.FriendlyName),
                SummaryTotal = summaryTotal.ToString("C", responseCulture)      // Currency format.
            });
        }
        /// <summary>
        /// Gets the subscriptions managed by customers and partners
        /// </summary>
        /// <returns>returns managed subscriptions view model</returns>
        private async Task <ManagedSubscriptionsViewModel> GetManagedSubscriptions()
        {
            DateTime startTime = DateTime.Now;

            string clientCustomerId = Principal.PartnerCenterCustomerId;

            // responseCulture determines decimals, currency and such
            CultureInfo responseCulture = new CultureInfo(ApplicationDomain.Instance.PortalLocalization.Locale);

            // localeSpecificApiClient allows pulling offer names localized to supported portal locales compatible with Offer API supported locales.
            IPartner localeSpecificPartnerCenterClient = ApplicationDomain.Instance.PartnerCenterClient.With(RequestContextFactory.Instance.Create(ApplicationDomain.Instance.PortalLocalization.OfferLocale));

            // Get all subscriptions of customer from PC
            ResourceCollection <Subscription> customerAllSubscriptions = await localeSpecificPartnerCenterClient.Customers.ById(clientCustomerId).Subscriptions.GetAsync().ConfigureAwait(false);

            IEnumerable <CustomerSubscriptionEntity> customerSubscriptions = await ApplicationDomain.Instance.CustomerSubscriptionsRepository.RetrieveAsync(clientCustomerId).ConfigureAwait(false);

            IEnumerable <PartnerOffer> allPartnerOffers = await ApplicationDomain.Instance.OffersRepository.RetrieveAsync().ConfigureAwait(false);

            IEnumerable <MicrosoftOffer> currentMicrosoftOffers = await ApplicationDomain.Instance.OffersRepository.RetrieveMicrosoftOffersAsync().ConfigureAwait(false);

            List <SubscriptionViewModel> customerSubscriptionsView = new List <SubscriptionViewModel>();

            // iterate through and build the list of customer's subscriptions.
            foreach (CustomerSubscriptionEntity subscription in customerSubscriptions)
            {
                PartnerOffer partnerOfferItem  = allPartnerOffers.FirstOrDefault(offer => offer.Id == subscription.PartnerOfferId);
                string       subscriptionTitle = partnerOfferItem.Title;
                string       portalOfferId     = partnerOfferItem.Id;
                decimal      portalOfferPrice  = partnerOfferItem.Price;

                DateTime subscriptionExpiryDate = subscription.ExpiryDate.ToUniversalTime();
                int      remainingDays          = (subscriptionExpiryDate.Date - DateTime.UtcNow.Date).Days;
                bool     isRenewable            = remainingDays <= 30;                                 // IsRenewable is true if subscription is going to expire in 30 days.
                bool     isEditable             = DateTime.UtcNow.Date <= subscriptionExpiryDate.Date; // IsEditable is true if today is lesser or equal to subscription expiry date.

                // Temporarily mark this partnerOffer item as inactive and dont allow store front customer to manage this subscription.
                MicrosoftOffer alignedMicrosoftOffer = currentMicrosoftOffers.FirstOrDefault(offer => offer.Offer.Id == partnerOfferItem.MicrosoftOfferId);

                if (alignedMicrosoftOffer == null)
                {
                    // The offer is inactive (marked for deletion) then dont allow renewals or editing on this subscription tied to this offer.
                    partnerOfferItem.IsInactive = true;
                    isRenewable = false;
                    isEditable  = false;
                }

                BrandingConfiguration portalBranding = await ApplicationDomain.Instance.PortalBranding.RetrieveAsync().ConfigureAwait(false);

                // Compute the pro rated price per seat for this subcription & return for client side processing during updates.
                decimal proratedPerSeatPrice = Math.Round(CommerceOperations.CalculateProratedSeatCharge(subscription.ExpiryDate,
                                                                                                         portalOfferPrice,
                                                                                                         portalBranding.BillingCycle),
                                                          Resources.Culture.NumberFormat.CurrencyDecimalDigits);

                SubscriptionViewModel subscriptionItem = new SubscriptionViewModel()
                {
                    SubscriptionId            = subscription.SubscriptionId,
                    FriendlyName              = subscriptionTitle,
                    PortalOfferId             = portalOfferId,
                    PortalOfferPrice          = portalOfferPrice.ToString("C", responseCulture),
                    IsRenewable               = isRenewable,
                    IsEditable                = isEditable,
                    SubscriptionExpiryDate    = subscriptionExpiryDate.Date.ToString("d", responseCulture),
                    SubscriptionProRatedPrice = proratedPerSeatPrice
                };

                // add this subcription to the customer's subscription list.
                customerSubscriptionsView.Add(subscriptionItem);
            }

            List <CustomerSubscriptionModel> customerManagedSubscriptions = new List <CustomerSubscriptionModel>();
            List <PartnerSubscriptionModel>  partnerManagedSubscriptions  = new List <PartnerSubscriptionModel>();

            // Divide the subscriptions by customer and partner
            foreach (Subscription customerSubscriptionFromPC in customerAllSubscriptions.Items)
            {
                SubscriptionViewModel subscription = customerSubscriptionsView.FirstOrDefault(sub => sub.SubscriptionId == customerSubscriptionFromPC.Id);

                // Customer managed subscription found
                if (subscription != null)
                {
                    CustomerSubscriptionModel customerSubscription = new CustomerSubscriptionModel()
                    {
                        SubscriptionId            = customerSubscriptionFromPC.Id,
                        LicensesTotal             = customerSubscriptionFromPC.Quantity.ToString("G", responseCulture),
                        Status                    = GetStatusType(customerSubscriptionFromPC.Status),
                        CreationDate              = customerSubscriptionFromPC.CreationDate.ToString("d", responseCulture),
                        FriendlyName              = subscription.FriendlyName,
                        IsRenewable               = subscription.IsRenewable,
                        IsEditable                = subscription.IsEditable,
                        PortalOfferId             = subscription.PortalOfferId,
                        SubscriptionProRatedPrice = subscription.SubscriptionProRatedPrice
                    };

                    customerManagedSubscriptions.Add(customerSubscription);
                }
                else
                {
                    PartnerSubscriptionModel partnerSubscription = new PartnerSubscriptionModel()
                    {
                        Id           = customerSubscriptionFromPC.Id,
                        OfferName    = customerSubscriptionFromPC.OfferName,
                        Quantity     = customerSubscriptionFromPC.Quantity.ToString("G", responseCulture),
                        Status       = GetStatusType(customerSubscriptionFromPC.Status),
                        CreationDate = customerSubscriptionFromPC.CreationDate.ToString("d", responseCulture),
                    };

                    partnerManagedSubscriptions.Add(partnerSubscription);
                }
            }

            ManagedSubscriptionsViewModel managedSubscriptions = new ManagedSubscriptionsViewModel()
            {
                CustomerManagedSubscriptions = customerManagedSubscriptions.OrderByDescending(customerManagedSubscription => customerManagedSubscription.CreationDate),
                PartnerManagedSubscriptions  = partnerManagedSubscriptions.OrderByDescending(partnerManagedSubscription => partnerManagedSubscription.CreationDate)
            };

            // Capture the request for customer managed subscriptions and partner managed subscriptions for analysis.
            Dictionary <string, string> eventProperties = new Dictionary <string, string> {
                { "CustomerId", clientCustomerId }
            };

            // Track the event measurements for analysis.
            Dictionary <string, double> eventMetrics = new Dictionary <string, double> {
                { "ElapsedMilliseconds", DateTime.Now.Subtract(startTime).TotalMilliseconds }, { "CustomerManagedSubscriptions", customerManagedSubscriptions.Count }, { "PartnerManagedSubscriptions", partnerManagedSubscriptions.Count }
            };

            ApplicationDomain.Instance.TelemetryService.Provider.TrackEvent("GetManagedSubscriptions", eventProperties, eventMetrics);

            return(managedSubscriptions);
        }
        /// <summary>
        /// Gets the summary of subscriptions for a portal customer.
        /// </summary>
        /// <param name="customerId">The customer Id.</param>
        /// <returns>Subscription Summary.</returns>
        private async Task <SubscriptionsSummary> GetSubscriptionSummary(string customerId)
        {
            var customerSubscriptionsTask        = ApplicationDomain.Instance.CustomerSubscriptionsRepository.RetrieveAsync(customerId);
            var customerSubscriptionsHistoryTask = ApplicationDomain.Instance.CustomerPurchasesRepository.RetrieveAsync(customerId);
            var allPartnerOffersTask             = ApplicationDomain.Instance.OffersRepository.RetrieveAsync();
            await Task.WhenAll(customerSubscriptionsTask, customerSubscriptionsHistoryTask, allPartnerOffersTask);

            var customerSubscriptionsHistory = customerSubscriptionsHistoryTask.Result;

            // retrieve all the partner offers to match against them
            IEnumerable <PartnerOffer> allPartnerOffers = allPartnerOffersTask.Result;

            // start building the summary.
            decimal summaryTotal = 0;

            // format all responses to client using portal locale.
            CultureInfo responseCulture = new CultureInfo(ApplicationDomain.Instance.PortalLocalization.Locale);
            List <SubscriptionViewModel> customerSubscriptionsView = new List <SubscriptionViewModel>();

            // iterate through and build the list of customer's subscriptions.
            foreach (var subscription in customerSubscriptionsTask.Result)
            {
                decimal subscriptionTotal = 0;
                int     licenseTotal      = 0;
                List <SubscriptionHistory> historyItems = new List <SubscriptionHistory>();

                // collect the list of history items for this subcription.
                var subscriptionHistoryList = customerSubscriptionsHistory
                                              .Where(historyItem => historyItem.SubscriptionId == subscription.SubscriptionId)
                                              .OrderBy(historyItem => historyItem.TransactionDate);

                // iterate through and build the SubsriptionHistory for this subscription.
                foreach (var historyItem in subscriptionHistoryList)
                {
                    decimal orderTotal = Math.Round(historyItem.SeatPrice * historyItem.SeatsBought, 2);
                    historyItems.Add(new SubscriptionHistory()
                    {
                        OrderTotal    = orderTotal.ToString("C", responseCulture),
                        PricePerSeat  = historyItem.SeatPrice.ToString("C", responseCulture),                     // Currency format.
                        SeatsBought   = historyItem.SeatsBought.ToString("G", responseCulture),                   // General format.
                        OrderDate     = historyItem.TransactionDate.ToLocalTime().ToString("d", responseCulture), // Short date format.
                        OperationType = this.GetOperationType(historyItem.PurchaseType)                           // Localized Operation type string.
                    });

                    // Increment the subscription total.
                    licenseTotal += historyItem.SeatsBought;

                    // Increment the subscription total.
                    subscriptionTotal += orderTotal;
                }

                var     partnerOfferItem  = allPartnerOffers.Where(offer => offer.Id == subscription.PartnerOfferId).FirstOrDefault();
                string  subscriptionTitle = partnerOfferItem.Title;
                string  portalOfferId     = partnerOfferItem.Id;
                decimal portalOfferPrice  = partnerOfferItem.Price;

                DateTime subscriptionExpiryDate = subscription.ExpiryDate.ToUniversalTime();
                int      remainingDays          = (subscriptionExpiryDate.Date - DateTime.UtcNow.Date).Days;
                bool     isRenewable            = remainingDays <= 30;
                bool     isEditable             = DateTime.UtcNow.Date <= subscriptionExpiryDate.Date;

                if (partnerOfferItem.IsInactive)
                {
                    // in case the offer is inactive (marked for deletion) then dont allow renewals or editing on this subscription tied to this offer.
                    isRenewable = false;
                    isEditable  = false;
                }

                // Compute the pro rated price per seat for this subcription & return for client side processing during updates.
                decimal proratedPerSeatPrice = Math.Round(CommerceOperations.CalculateProratedSeatCharge(subscription.ExpiryDate, portalOfferPrice), 2);

                SubscriptionViewModel subscriptionItem = new SubscriptionViewModel()
                {
                    SubscriptionId            = subscription.SubscriptionId,
                    FriendlyName              = subscriptionTitle,
                    PortalOfferId             = portalOfferId,
                    PortalOfferPrice          = portalOfferPrice.ToString("C", responseCulture),
                    IsRenewable               = isRenewable,                                                // IsRenewable is true if subscription is going to expire in 30 days.
                    IsEditable                = isEditable,                                                 // IsEditable is true if today is lesser or equal to subscription expiry date.
                    LicensesTotal             = licenseTotal.ToString("G", responseCulture),                // General format.
                    SubscriptionTotal         = subscriptionTotal.ToString("C", responseCulture),           // Currency format.
                    SubscriptionExpiryDate    = subscriptionExpiryDate.Date.ToString("d", responseCulture), // Short date format.
                    SubscriptionOrderHistory  = historyItems,
                    SubscriptionProRatedPrice = proratedPerSeatPrice
                };

                // add this subcription to the customer's subscription list.
                customerSubscriptionsView.Add(subscriptionItem);

                // Increment the summary total.
                summaryTotal += subscriptionTotal;
            }

            // Sort List of subscriptions based on portal offer name.
            return(new SubscriptionsSummary()
            {
                Subscriptions = customerSubscriptionsView.OrderBy(subscriptionItem => subscriptionItem.FriendlyName),
                SummaryTotal = summaryTotal.ToString("C", responseCulture)      // Currency format.
            });
        }