Пример #1
0
        protected override string GetCsvReportItemFormated(ReportOutputItem reportOutputItem)
        {
            if (reportOutputItem.GetType() != typeof(CustomerUsageReportOutputItem))
            {
                throw new ArgumentException("Report Output Item must be of type CustomerUsageReportOutputItem");
            }

            CustomerUsageReportOutputItem customerUsageReportOutputItem = reportOutputItem as CustomerUsageReportOutputItem;

            StringBuilder result = new StringBuilder();

            result.AppendFormat("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\t{9}\t{10}\t{11}\t{12}\t{13}\t{14}\t{15}\t{16}",
                                customerUsageReportOutputItem.Customer.Id, customerUsageReportOutputItem.Customer.CompanyProfile.TenantId,
                                customerUsageReportOutputItem.Customer.CompanyProfile.CompanyName, customerUsageReportOutputItem.OnMicrosoftDomain,
                                customerUsageReportOutputItem.DefaultDomain, customerUsageReportOutputItem.SubscriptionId,
                                customerUsageReportOutputItem.SubscriptionStatus, customerUsageReportOutputItem.SubscriptionQuantity,
                                customerUsageReportOutputItem.OfferName, customerUsageReportOutputItem.SKUPartNumber,
                                customerUsageReportOutputItem.SKUTotalServices,
                                customerUsageReportOutputItem.SKUService, customerUsageReportOutputItem.SKUServiceProvisioningStatus,
                                customerUsageReportOutputItem.SKUAssignedSeats.ToString(), customerUsageReportOutputItem.SKUServiceActiveUsers.ToString(),
                                customerUsageReportOutputItem.GlobalActionType, customerUsageReportOutputItem.GlobalActionSubType);

            return(result.ToString());
        }
Пример #2
0
        public override async Task ReportItemProcessorFunctionAsync(
            BlockingCollection <ReportOutputItem> results,
            List <PartnerSdkModels.Customers.Customer> customers, PartnerSdkModels.Customers.Customer customer,
            int currentPage)
        {
            _logger.Info(string.Format("Thread: {0} Batch: {1}. Processing customer: {2} ({3}/{4}) / (ID: {5} - CID: {6} - TD: {7})",
                                       Thread.CurrentThread.ManagedThreadId, currentPage,
                                       customer.CompanyProfile.CompanyName, customers.IndexOf(customer) + 1, customers.Count,
                                       customer.Id, customer.CommerceId, customer.CompanyProfile.Domain));

            CustomerUsageReportOutputItem reportOutputItem = new CustomerUsageReportOutputItem()
            {
                Customer = customer
            };

            #region Execute base customer validations

            if (ExecuteReportItemProcessorCustomerBaseValidations(reportOutputItem, results, customer))
            {
                // Customer matched one of the validations. Return
                return;
            }

            #endregion

            try
            {
                #region Get customer domains

                // NOTE: We always include the customer domains, to include this info in the report,
                // even if the customer does not have any subscribed SKUs

                _logger.Debug("GetCustomerDomains");
                List <Domain> customerDomains = Program.GetCustomerDomains(customer);
                // Extract domains information
                reportOutputItem.OnMicrosoftDomain = customerDomains.FirstOrDefault(domain => domain.IsInitial && domain.IsVerified).Name;
                reportOutputItem.DefaultDomain     = customerDomains.FirstOrDefault(domain => domain.IsDefault && domain.IsVerified).Name;

                #endregion

                #region Get Subscribed Skus information

                _logger.Debug("GetCustomerSubscribedSkus");
                List <SubscribedSku> customerSubscribedSkus = await Program.GetCustomerSubscribedSkus(customer);

                #region Execute base subscribed Skus validations

                if (ExecuteReportItemProcessorSubscribedSkusBaseValidations(reportOutputItem, results, customer, customerSubscribedSkus))
                {
                    // Matched one of the validations. Return
                    return;
                }

                #endregion

                #endregion

                #region Get Subscriptions information

                _logger.Debug("GetCustomerSubscriptions");
                List <PartnerSdkModels.Subscriptions.Subscription> customerSubscriptions =
                    await Program.GetCustomerSubscriptions(customer);

                #region Execute base subscriptions validations

                if (ExecuteReportItemProcessorSubscriptionsBaseValidations(reportOutputItem, results, customer, customerSubscriptions))
                {
                    // Matched one of the validations. Return
                    return;
                }

                #endregion

                #endregion

                #region Extract information from each subscription

                foreach (PartnerSdkModels.Subscriptions.Subscription subscription in customerSubscriptions)
                {
                    _logger.Info(string.Format("Processing subscription: {0} ({1}/{2})",
                                               subscription.FriendlyName, customerSubscriptions.IndexOf(subscription) + 1,
                                               customerSubscriptions.Count));

                    reportOutputItem.SubscriptionId       = Guid.Parse(subscription.Id);
                    reportOutputItem.SubscriptionStatus   = subscription.Status.ToString();
                    reportOutputItem.SubscriptionQuantity = (uint)subscription.Quantity;

                    if (subscription.Status != PartnerSdkModels.Subscriptions.SubscriptionStatus.Active)
                    {
                        // Subscription is not active. Nothing to do
                        reportOutputItem.GlobalActionType    = "ACTIVATION OPPORTUNITY";
                        reportOutputItem.GlobalActionSubType = "Subscription state: " + subscription.Status.ToString();
                        results.Add(Program.Clone(reportOutputItem));
                        return;
                    }

                    // Subscription Offer information
                    // This is necessary to match Subscribed SKU to a Subscription
                    // Subscribed SKU has the SKU Product ID field
                    // Subscription has the Offer ID field
                    // The Offer detail is the connection between them, because the Offer has the Offer ID and the Product ID
                    _logger.Debug("GetSubscriptionOffer");
                    PartnerSdkModels.Offers.Offer subscriptionOffer = await Program.GetOfferById(subscription.OfferId.ToString());

                    reportOutputItem.OfferName = subscriptionOffer.Name;

                    // Subscription SKU
                    SubscribedSku subscriptionSubscribedSku = customerSubscribedSkus.FirstOrDefault(sku =>
                                                                                                    sku.SkuId.ToString().Equals(subscriptionOffer.Product.Id, StringComparison.InvariantCultureIgnoreCase));

                    if (subscriptionSubscribedSku == null)
                    {
                        reportOutputItem.GlobalActionType    = "Not supported";
                        reportOutputItem.GlobalActionSubType = "Subscription Offer does not map to any CSP Subscribed SKU Product";
                        results.Add(Program.Clone(reportOutputItem));
                        continue;
                    }

                    reportOutputItem.SKUPartNumber    = subscriptionSubscribedSku.SkuPartNumber;
                    reportOutputItem.SKUTotalServices = subscriptionSubscribedSku.ServicePlans.Count();
                    reportOutputItem.SKUAssignedSeats = subscriptionSubscribedSku.ConsumedUnits;

                    #region Extract global user's information (in terms of number of users, not detailed user's information)

                    // For tenant level information
                    // Ex: Subscription is for 20 seats, but only 5 are using each of the services?

                    foreach (ServicePlanInfo servicePlan in subscriptionSubscribedSku.ServicePlans)
                    {
                        _logger.Info(string.Format("Processing SKU Service Plan: {0} ({1}/{2})",
                                                   servicePlan.ServicePlanName, subscriptionSubscribedSku.ServicePlans.IndexOf(servicePlan) + 1,
                                                   subscriptionSubscribedSku.ServicePlans.Count));

                        reportOutputItem.SKUService = servicePlan.ServicePlanName;
                        reportOutputItem.SKUServiceProvisioningStatus = servicePlan.ProvisioningStatus.ToString();

                        switch (servicePlan.ServicePlanName)
                        {
                        case "EXCHANGE_S_STANDARD":
                        case "EXCHANGE_S_DESKLESS":
                            CustomerMailboxUsageReport customerMailboxUsageReport = Program.GetCustomerMailboxUsageReport(customer);
                            reportOutputItem.SKUServiceActiveUsers = customerMailboxUsageReport.TotalMailboxCount;
                            break;

                        case "MCOSTANDARD":
                            CustomerCsActiveUserReport customerCsActiveUserReport = Program.GetCustomerCsActiveUserReport(customer);
                            reportOutputItem.SKUServiceActiveUsers = customerCsActiveUserReport.ActiveUsers;
                            break;

                        case "SHAREPOINTSTANDARD":
                            CustomerSPOActiveUserReport customerSPOActiveUserReport = Program.GetCustomerSPOActiveUserReport(customer);
                            reportOutputItem.SKUServiceActiveUsers = customerSPOActiveUserReport.UniqueUsers;

                            // Also has OneDrive ?????
                            // CustomerSPOSkyDriveProDeployedReport customerSPOSkyDriveProDeployedReport = await Program.GetCustomerSPOSkyDriveProDeployedReport(customer);
                            //reportOutputItem.SKUServiceActiveUsers = customerSPOSkyDriveProDeployedReport.Active;
                            break;

                        case "SHAREPOINTWAC":
                        case "OFFICE_BUSINESS":
                        case "OFFICESUBSCRIPTION":
                        case "ONEDRIVEENTERPRISE":
                        case "ONEDRIVESTANDARD":
                        case "SWAY":
                        case "INTUNE_O365":
                        case "YAMMER_ENTERPRISE":
                        default:
                            reportOutputItem.GlobalActionType    = "Not supported";
                            reportOutputItem.GlobalActionSubType = "Service Plan information extraction not supported";
                            results.Add(Program.Clone(reportOutputItem));
                            continue;
                        }

                        if (reportOutputItem.SKUServiceActiveUsers < reportOutputItem.SKUAssignedSeats)
                        {
                            reportOutputItem.GlobalActionType    = "ACTIVATION OPPORTUNITY";
                            reportOutputItem.GlobalActionSubType = "Not all users are active on the service";
                        }
                        else
                        {
                            reportOutputItem.GlobalActionType    = "NO ACTION NEEDED";
                            reportOutputItem.GlobalActionSubType = "All users are active on the service";
                        }

                        results.Add(Program.Clone(reportOutputItem));
                    }

                    #endregion
                }

                #endregion
            }
            catch (Exception ex)
            {
                _logger.Warn("Error: " + ex.ToString());

                reportOutputItem.GlobalActionType    = "ERROR";
                reportOutputItem.GlobalActionSubType = ex.ToString().Replace("\r\n", " ").Replace("\n", " ").Replace("\t", " ");
                results.Add(Program.Clone(reportOutputItem));
            }
        }