public static async Task <List <PartnerSdkModels.Subscriptions.Subscription> > GetCustomerSubscriptions( PartnerSdkModels.Customers.Customer customer) { // Get the subscriptions for the customer return((await _partnerOperations.Customers.ById(customer.Id.ToString()).Subscriptions.GetAsync()) .Items.ToList()); }
public async Task <string> MicosoftCloudAgreement(Microsoft.Store.PartnerCenter.Models.Customers.Customer newCustomer) { //BrandingConfiguration branding = await ApplicationDomain.Instance.PortalBranding.RetrieveAsync().ConfigureAwait(false); ResourceCollection <AgreementMetaData> agreements = await ApplicationDomain.Instance.PartnerCenterClient.AgreementDetails.GetAsync().ConfigureAwait(false); // Obtain reference to the Microsoft Cloud Agreement. AgreementMetaData microsoftCloudAgreement = agreements.Items.FirstOrDefault(agr => agr.AgreementType == Microsoft.Store.PartnerCenter.Models.Agreements.AgreementType.MicrosoftCloudAgreement); // Attest that the customer has accepted the Microsoft Cloud Agreement (MCA). await ApplicationDomain.Instance.PartnerCenterClient.Customers[newCustomer.Id].Agreements.CreateAsync( new Agreement { DateAgreed = DateTime.UtcNow, PrimaryContact = new Microsoft.Store.PartnerCenter.Models.Agreements.Contact { Email = newCustomer.BillingProfile.Email, //customerRegistrationInfoPersisted.Email, FirstName = newCustomer.BillingProfile.DefaultAddress.FirstName, //customerRegistrationInfoPersisted.FirstName, LastName = newCustomer.BillingProfile.DefaultAddress.LastName, //customerRegistrationInfoPersisted.LastName, PhoneNumber = newCustomer.BillingProfile.DefaultAddress.PhoneNumber, //customerRegistrationInfoPersisted.Phone }, TemplateId = microsoftCloudAgreement.TemplateId, Type = Microsoft.Store.PartnerCenter.Models.Agreements.AgreementType.MicrosoftCloudAgreement, //Ahsan UserId = "631c1b48-e58c-46d4-a947-e7cea8b3d796", //branding.AgreementUserId }).ConfigureAwait(false); return(newCustomer.CompanyProfile.TenantId); }
public static DatabaseModel.Customer MapFromSource(PartnerSdkModels.Customers.Customer source) { Guid tenantId; return(new DatabaseModel.Customer() { Id = Guid.Parse(source.Id), TenantId = source.CompanyProfile != null && !string.IsNullOrWhiteSpace(source.CompanyProfile.TenantId) && Guid.TryParse(source.CompanyProfile.TenantId, out tenantId) ? tenantId : Guid.Empty, CompanyName = source.CompanyProfile != null && !string.IsNullOrWhiteSpace(source.CompanyProfile.TenantId) ? source.CompanyProfile.CompanyName : string.Empty, AddressLine1 = source.BillingProfile != null && source.BillingProfile.DefaultAddress != null && !string.IsNullOrWhiteSpace(source.BillingProfile.DefaultAddress.AddressLine1) ? source.BillingProfile.DefaultAddress.AddressLine1 : string.Empty, AddressLine2 = source.BillingProfile != null && source.BillingProfile.DefaultAddress != null && !string.IsNullOrWhiteSpace(source.BillingProfile.DefaultAddress.AddressLine2) ? source.BillingProfile.DefaultAddress.AddressLine2 : string.Empty, City = source.BillingProfile != null && source.BillingProfile.DefaultAddress != null && !string.IsNullOrWhiteSpace(source.BillingProfile.DefaultAddress.City) ? source.BillingProfile.DefaultAddress.City : string.Empty, Country = source.BillingProfile != null && source.BillingProfile.DefaultAddress != null && !string.IsNullOrWhiteSpace(source.BillingProfile.DefaultAddress.Country) ? source.BillingProfile.DefaultAddress.Country : string.Empty, PostalCode = source.BillingProfile != null && source.BillingProfile.DefaultAddress != null && !string.IsNullOrWhiteSpace(source.BillingProfile.DefaultAddress.PostalCode) ? source.BillingProfile.DefaultAddress.PostalCode : string.Empty, Region = source.BillingProfile != null && source.BillingProfile.DefaultAddress != null && !string.IsNullOrWhiteSpace(source.BillingProfile.DefaultAddress.Region) ? source.BillingProfile.DefaultAddress.Region : string.Empty, State = source.BillingProfile != null && source.BillingProfile.DefaultAddress != null && !string.IsNullOrWhiteSpace(source.BillingProfile.DefaultAddress.State) ? source.BillingProfile.DefaultAddress.State : string.Empty, }); }
protected bool ExecuteReportItemProcessorCustomerBaseValidations( ReportOutputItem reportOutputItem, BlockingCollection <ReportOutputItem> results, PartnerSdkModels.Customers.Customer customer) { if (string.IsNullOrWhiteSpace(customer.Id)) { reportOutputItem.GlobalActionType = "NO ACTION NEEDED"; reportOutputItem.GlobalActionSubType = "Customer is deleted or without relationship"; results.Add(Program.Clone(reportOutputItem)); return(true); } if (customer.RelationshipToPartner != PartnerSdkModels.Customers.CustomerPartnerRelationship.Reseller) { // TODO: Check other kind of relationships reportOutputItem.GlobalActionType = "ACTIVATION OPPORTUNITY"; reportOutputItem.GlobalActionSubType = "Customer relationship to partner different from reseller"; results.Add(Program.Clone(reportOutputItem)); return(true); } // Didnt matched any validation return(false); }
public static DatabaseEntities.MarketingCampaignsCustomer MapFromSource(PartnerSdkModels.Customers.Customer source) { Guid customerId; return(new DatabaseEntities.MarketingCampaignsCustomer() { CustomerId = !string.IsNullOrEmpty(source.Id) && Guid.TryParse(source.Id, out customerId) ? customerId : Guid.Empty }); }
public static DatabaseEntities.Customer MapFromSource(PartnerSdkModels.Customers.Customer source) { Guid tenantId; return(new DatabaseEntities.Customer() { Id = Guid.Parse(source.Id), TenantId = source.CompanyProfile != null && !string.IsNullOrEmpty(source.CompanyProfile.TenantId) && Guid.TryParse(source.CompanyProfile.TenantId, out tenantId) ? tenantId : Guid.Empty, CompanyName = source.CompanyProfile != null && !string.IsNullOrEmpty(source.CompanyProfile.TenantId) ? source.CompanyProfile.CompanyName : string.Empty }); }
public static List <Domain> GetCustomerDomains(PartnerSdkModels.Customers.Customer customer) { List <Domain> result = new List <Domain>(); // Initialize the Azure AD Graph API helper with the customer tenant _azureADGraphApiHelper = new AzureADGraphApiHelper(customer.Id); // Get request client HttpWebRequest request = _azureADGraphApiHelper.BuildGetCustomerDomainsRequest(); // Execute request dynamic requestResult = request.TryCatchRequest(); foreach (dynamic domain in requestResult.value) { result.Add(DomainMapper.MapFromJson(customer.Id, domain)); } return(result); }
protected bool ExecuteReportItemProcessorSubscriptionsBaseValidations( ReportOutputItem reportOutputItem, BlockingCollection <ReportOutputItem> results, PartnerSdkModels.Customers.Customer customer, List <PartnerSdkModels.Subscriptions.Subscription> customerSubscriptions) { if (customerSubscriptions.Count == 0) { // Customer does not have any subscribed SKUs reportOutputItem.GlobalActionType = "ACTIVATION OPPORTUNITY"; reportOutputItem.GlobalActionSubType = "Customer does not have any subscriptions"; results.Add(Program.Clone(reportOutputItem)); return(true); } // Didnt matched any validation return(false); }
public static CustomerSPOActiveUserReport GetCustomerSPOActiveUserReport( PartnerSdkModels.Customers.Customer customer) { string script = string.Format("Get-SPOActiveUserReport -ReportType Monthly -ResultSize unlimited -StartDate {0} -EndDate {1}", DateTime.Now.AddDays(-30).ToString("MM/dd/yyyy"), DateTime.Now.ToString("MM/dd/yyyy")); var result = PowerShellHelper.ExecuteExchangeOnlinePowerShellScript(customer.Id, script); if (result.Count() > 0) { return(CustomerSPOActiveUserReportMapper.MapFromObject(Guid.Parse(customer.Id), result[0])); } // else. Return empty object return(new CustomerSPOActiveUserReport() { CustomerId = Guid.Parse(customer.Id) }); }
public static async Task <List <SubscribedSku> > GetCustomerSubscribedSkus( PartnerSdkModels.Customers.Customer customer) { AzureADGraphApiHelper azureADGraphApiHelper = new AzureADGraphApiHelper(customer.Id); GraphClient.ActiveDirectoryClient activeDirectoryClient = azureADGraphApiHelper.GetActiveDirectoryClient(); GraphClient.Extensions.IPagedCollection <GraphClient.ISubscribedSku> subscribedSkus = await activeDirectoryClient.SubscribedSkus.ExecuteAsync(); List <SubscribedSku> result = new List <SubscribedSku>(); do { foreach (GraphClient.ISubscribedSku subscribedSku in subscribedSkus.CurrentPage.ToList()) { result.Add(SubscribedSkuMapper.MapFromSource(subscribedSku)); } subscribedSkus = await subscribedSkus.GetNextPageAsync(); }while (subscribedSkus != null && subscribedSkus.MorePagesAvailable); return(result); }
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)); ActivationReportOutputItem reportOutputItem = new ActivationReportOutputItem() { Customer = customer }; #region Execute base customer validations if (ExecuteReportItemProcessorCustomerBaseValidations(reportOutputItem, results, 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"); reportOutputItem.CustomerDomains = Program.GetCustomerDomains(customer); #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 Get Subscription Offers 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("GetSubscriptionsOffers"); List <PartnerSdkModels.Offers.Offer> subscriptionsOffers = await Program.GetCustomerSubscriptionsOffers(customerSubscriptions); #endregion #region Process each subscribed Sku foreach (SubscribedSku subscribedSku in customerSubscribedSkus) { #region Extract Sku information _logger.Info(string.Format("Processing subscribedSku: {0} ({1}/{2})", subscribedSku.SkuPartNumber, customerSubscribedSkus.IndexOf(subscribedSku) + 1, customerSubscribedSkus.Count)); // Create new subscribed sku report output item ActivationReportSubscribedSKUOutputItem skuAndSubscriptions = new ActivationReportSubscribedSKUOutputItem() { SubscribedSKU = subscribedSku }; // Try to match subscribedSku with corresponding subscription offer // to get subscribed sku subscriptions // Get the offer detail that matches the subscribed SKU product ID PartnerSdkModels.Offers.Offer skuOfferDetail = subscriptionsOffers.FirstOrDefault(offer => offer.Product.Id.Equals(subscribedSku.SkuId.ToString(), StringComparison.InvariantCultureIgnoreCase)); if (skuOfferDetail != null) { // Extract offer and subscribed Sku subscriptions skuAndSubscriptions.Offer = skuOfferDetail; // Filter all the SKU subscriptions by the offer id skuAndSubscriptions.SKUSubscriptions = customerSubscriptions.Where(subscription => subscription.OfferId.ToString().Equals(skuOfferDetail.Id, StringComparison.InvariantCultureIgnoreCase)).ToList(); } else { // No offer detail for the subscribed sku. Could not match subscriptions to subscribed Sku skuAndSubscriptions.Offer = null; skuAndSubscriptions.ActionType = "ACTIVATION OPPORTUNITY"; skuAndSubscriptions.ActionSubType = "Not a CSP offer"; reportOutputItem.CustomerSubscribedSkuAndSubscriptions.Add(Program.Clone(skuAndSubscriptions)); continue; } skuAndSubscriptions.ActiveSeats = subscribedSku.PrepaidUnits.Enabled; skuAndSubscriptions.InGracePeriodSeats = subscribedSku.PrepaidUnits.Warning; skuAndSubscriptions.DisabledSeats = subscribedSku.PrepaidUnits.Suspended; skuAndSubscriptions.AssignedSeats = subscribedSku.ConsumedUnits; if (!subscribedSku.CapabilityStatus.Equals("Enabled", StringComparison.InvariantCultureIgnoreCase)) { // Sku capability is different from enabled skuAndSubscriptions.ActionType = "ACTIVATION OPPORTUNITY"; skuAndSubscriptions.ActionSubType = "SKU capability status not enabled"; // Add processed subscribed SKU to customer reportOutputItem.CustomerSubscribedSkuAndSubscriptions.Add(Program.Clone(skuAndSubscriptions)); continue; } #endregion #region Execute activation action analysis logic #region Check when no seats are assigned if (skuAndSubscriptions.AssignedSeats == 0) { #region Check when no seats are assigned, and no seats are active if (skuAndSubscriptions.ActiveSeats == 0) { // No seats assigned, and not active seats if (skuAndSubscriptions.InGracePeriodSeats == 0) { if (skuAndSubscriptions.DisabledSeats == 0) { skuAndSubscriptions.ActionType = "ACTIVATION OPPORTUNITY"; skuAndSubscriptions.ActionSubType = "No seats active, assigned, about to expire or disabled"; } if (skuAndSubscriptions.DisabledSeats > 0) { skuAndSubscriptions.ActionType = "NO ACTION NEEDED"; skuAndSubscriptions.ActionSubType = "Waiting for subscription life cycle to de-provision subscription"; } } if (skuAndSubscriptions.InGracePeriodSeats > 0) { skuAndSubscriptions.ActionType = "ACTIVATION OPPORTUNITY"; skuAndSubscriptions.ActionSubType = "No seats assigned yet, all licenses are about to expire"; } } #endregion #region Check when no seats are assigned, but there are active seats if (skuAndSubscriptions.ActiveSeats > 0) { // No seats assigned, but there are active seats if (skuAndSubscriptions.InGracePeriodSeats == 0) { // There are active seats, none about to expire, but no assigned seats skuAndSubscriptions.ActionType = "ACTIVATION OPPORTUNITY"; skuAndSubscriptions.ActionSubType = "No seats assigned yet"; } if (skuAndSubscriptions.InGracePeriodSeats > 0) { // There are active and about to expire seats, but no assigned seats skuAndSubscriptions.ActionType = "ACTIVATION OPPORTUNITY"; skuAndSubscriptions.ActionSubType = "No seats assigned yet, some licenses are about to expire"; } } #endregion } #endregion #region Check when there are assigned seats if (skuAndSubscriptions.AssignedSeats > 0) { // Seats are assigned. Check other conditions #region Check comparison between active and assigned seats if (skuAndSubscriptions.ActiveSeats == skuAndSubscriptions.AssignedSeats && skuAndSubscriptions.InGracePeriodSeats == 0) { // There are active seats and all are assigned // No seats are disabled or about to expire skuAndSubscriptions.ActionType = "NO ACTION NEEDED"; skuAndSubscriptions.ActionSubType = "All active licenses are assigned"; reportOutputItem.CustomerSubscribedSkuAndSubscriptions.Add(Program.Clone(skuAndSubscriptions)); continue; } if ((skuAndSubscriptions.ActiveSeats + skuAndSubscriptions.InGracePeriodSeats) == skuAndSubscriptions.AssignedSeats) { // The sum of the active and about to expire seats is equal to the assigned seats // These are assigned aeats, and also disabled seats skuAndSubscriptions.ActionType = "ACTION NEEDED"; skuAndSubscriptions.ActionSubType = "All licenses assigned. Some licenses are about to expire"; reportOutputItem.CustomerSubscribedSkuAndSubscriptions.Add(Program.Clone(skuAndSubscriptions)); continue; } if ((skuAndSubscriptions.ActiveSeats + skuAndSubscriptions.InGracePeriodSeats) > skuAndSubscriptions.AssignedSeats) { // The sum of the active and about to expire seats is greater than the assigned seats and // There are assigned seats and no disabled seats skuAndSubscriptions.ActionType = "ACTIVATION OPPORTUNITY"; skuAndSubscriptions.ActionSubType = "Not all seats have been assigned yet"; reportOutputItem.CustomerSubscribedSkuAndSubscriptions.Add(Program.Clone(skuAndSubscriptions)); continue; } if ((skuAndSubscriptions.ActiveSeats + skuAndSubscriptions.InGracePeriodSeats) < skuAndSubscriptions.AssignedSeats) { // The are assigned seats and they are fewer than the active plus the about to expire seats skuAndSubscriptions.ActionType = "ACTION NEEDED"; skuAndSubscriptions.ActionSubType = "Customer has more users with licenses than licenses available"; reportOutputItem.CustomerSubscribedSkuAndSubscriptions.Add(Program.Clone(skuAndSubscriptions)); continue; } #endregion } #endregion // If it didnt match with anything if (string.IsNullOrWhiteSpace(skuAndSubscriptions.ActionType)) { skuAndSubscriptions.ActionType = "Scenario not defined"; } // Add processed subscribed SKU to customer reportOutputItem.CustomerSubscribedSkuAndSubscriptions.Add(Program.Clone(skuAndSubscriptions)); #endregion } // Add customer processing to all results results.Add(Program.Clone(reportOutputItem)); #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)); } }
//Accept the request reseller public async Task <string> AcceptRequest(TMRC_CSP.Models.Customers _resellerRequest, int ResellerId = 0) { var db = new Context.ConnectionStringsContext(); try { //var obj = (Models.Customers)HttpContext.Current.Session["_resellerRequest"]; // TODO :: Loc. may need special handling for national clouds deployments (China). string domainName = string.Format(CultureInfo.InvariantCulture, "{0}.onmicrosoft.com", _resellerRequest.PrimaryDomain); // check domain available. bool isDomainTaken = await ApplicationDomain.Instance.PartnerCenterClient.Domains.ByDomain(domainName).ExistsAsync().ConfigureAwait(false); if (isDomainTaken) { return("Domain name already exist"); } // get the locale, we default to the first locale used in a country for now. Microsoft.Store.PartnerCenter.Models.CountryValidationRules.CountryValidationRules customerCountryValidationRules = await ApplicationDomain.Instance.PartnerCenterClient.CountryValidationRules.ByCountry(_resellerRequest.Country).GetAsync().ConfigureAwait(false); string billingCulture = customerCountryValidationRules.SupportedCulturesList.FirstOrDefault(); // default billing culture is the first supported culture for the customer's selected country. string billingLanguage = customerCountryValidationRules.SupportedLanguagesList.FirstOrDefault(); // default billing culture is the first supported language for the customer's selected country. //Add Customer to Partner center Customers cus = new Customers(ApplicationDomain.Instance); Microsoft.Store.PartnerCenter.Models.Customers.Customer newcustomer = cus.CreateCustomer(_resellerRequest, domainName, billingCulture, billingLanguage); Models.Customers res; if (db.Customers.Any(m => m.Id == _resellerRequest.Id)) //For Update { res = db.Customers.Where(m => m.Id == _resellerRequest.Id).SingleOrDefault(); res.Address1 = _resellerRequest.Address1; res.Address2 = _resellerRequest.Address2; res.City = _resellerRequest.City; res.Province = _resellerRequest.Province; res.ZipCode = _resellerRequest.ZipCode; res.Country = _resellerRequest.Country; res.PhoneNumber = _resellerRequest.PhoneNumber; res.FirstName = _resellerRequest.FirstName; res.LastName = _resellerRequest.LastName; res.Email = _resellerRequest.Email; res.Company = _resellerRequest.Company; res.MicrosoftId = newcustomer.Id; res.PrimaryDomain = domainName; res.VerifiedDate = DateTime.Now; res.IsVerified = true; res.IsAcceptTerms = _resellerRequest.IsAcceptTerms; } else //For Adding { res = new Models.Customers() { Address1 = _resellerRequest.Address1, Address2 = _resellerRequest.Address2, City = _resellerRequest.City, Province = _resellerRequest.Province, ZipCode = _resellerRequest.ZipCode, Country = _resellerRequest.Country, PhoneNumber = _resellerRequest.PhoneNumber, //Language = customerViewModel.Language, FirstName = _resellerRequest.FirstName, LastName = _resellerRequest.LastName, Email = _resellerRequest.Email, Company = _resellerRequest.Company, MicrosoftId = newcustomer.Id, //UserName = customerViewModel.Email, // BillingLanguage = billingLanguage, // BillingCulture = billingCulture, PrimaryDomain = domainName, //DomainPrefix = customerViewModel.DomainPrefix, VerifiedDate = DateTime.Now, IsVerified = true, IsAcceptTerms = _resellerRequest.IsAcceptTerms, AdditionalInfo = "", Status = true, CreatedDate = DateTime.Now, UserName = newcustomer.UserCredentials.UserName, Password = newcustomer.UserCredentials.Password, ResellerId = ResellerId }; db.Customers.Add(res); } db.SaveChanges(); ViewModel.OffersSetup.Agreements agr = new OffersSetup.Agreements(); await agr.MicosoftCloudAgreement(newcustomer); return(res.MicrosoftId); } catch { return("Unknown error occur"); } }
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)); } }
public abstract Task ReportItemProcessorFunctionAsync( BlockingCollection <ReportOutputItem> results, List <PartnerSdkModels.Customers.Customer> customers, PartnerSdkModels.Customers.Customer customer, int currentPage);