/// <summary> /// Adjusts a FaceIJK address in place so that the resulting cell address is /// relative to the correct icosahedral face. /// </summary> /// <param name="fijk">The FaceIJK address of the cell.</param> /// <param name="res">The H3 resolution of the cell.</param> /// <param name="pentLeading4">Whether or not the cell is a pentagon with a leading figit 4</param> /// <param name="substrate">Whether or not the cell is in a substrate grid.</param> /// <returns> /// Tuple /// Item1: <see cref="Overage"/> /// Item2: Adjusted <see cref="FaceIjk"/> /// </returns> /// <!-- /// faceijk.c /// Overage _adjustOverageClassII /// --> public static (Overage, FaceIjk) AdjustOverageClassIi( this FaceIjk fijk, int res, int pentLeading4, int substrate ) { Overage overage = Overage.NO_OVERAGE; var ijk = fijk.Coord; // get the maximum dimension value; scale if a substrate grid int maxDim = Constants.FaceIjk.MaxDimByCiiRes[res]; if (substrate != 0) { maxDim *= 3; } // check for overage if (substrate != 0 && ijk.Sum() == maxDim) // on edge { overage = Overage.FACE_EDGE; } else if (ijk.Sum() > maxDim) // overage { overage = Overage.NEW_FACE; FaceOrientIjk fijkOrient; if (ijk.K > 0) { if (ijk.J > 0) // jk "quadrant" { fijkOrient = Constants.FaceIjk.FaceNeighbors[fijk.Face, Constants.FaceIjk.JK]; } else // ik "quadrant" { fijkOrient = Constants.FaceIjk.FaceNeighbors[fijk.Face, Constants.FaceIjk.KI]; // adjust for the pentagonal missing sequence if (pentLeading4 != 0) { // translate origin to center of pentagon var origin = new CoordIjk(maxDim, 0, 0); var tmp = ijk - origin; // rotate to adjust for the missing sequence tmp = tmp.Rotate60Clockwise(); // translate the origin back to the center of the triangle ijk = tmp + origin; } } } else // ij "quadrant" { fijkOrient = Constants.FaceIjk.FaceNeighbors[fijk.Face, Constants.FaceIjk.IJ]; } fijk = fijk.ReplaceFace(fijkOrient.Face); // rotate and translate for adjacent face for (int i = 0; i < fijkOrient.Ccw60Rotations; i++) { ijk = ijk.Rotate60CounterClockwise(); } var transVec = fijkOrient.Translate; int unitScale = Constants.FaceIjk.UnitScaleByCiiRes[res]; if (substrate != 0) { unitScale *= 3; } transVec *= unitScale; ijk += transVec; ijk = ijk.Normalized(); // overage points on pentagon boundaries can end up on edges if (substrate != 0 && ijk.Sum() == maxDim) // on edge { overage = Overage.FACE_EDGE; } } fijk = fijk.ReplaceCoord(ijk); return(overage, fijk); }
/// <summary> /// Executes the scenario. /// </summary> protected override void RunScenario() { var partnerOperations = this.Context.UserPartnerOperations; string customerId = this.ObtainCustomerId(); this.Context.ConsoleHelper.StartProgress("Getting subscription overage"); var overage = partnerOperations.Customers.ById(customerId).Subscriptions.Overage.Get(); this.Context.ConsoleHelper.StopProgress(); this.Context.ConsoleHelper.WriteObject(overage, "Existing overage"); this.Context.ConsoleHelper.StartProgress("Getting subscription"); var subscriptions = partnerOperations.Customers.ById(customerId).Subscriptions.Get(); if (!subscriptions.Items.Any(sub => sub.ConsumptionType == "overage")) { this.Context.ConsoleHelper.Error("No overage eligible subscription found for the customer"); return; } this.Context.ConsoleHelper.StopProgress(); string azureEntitlementIdForOverage = null; string partnerId = null; var modernAzureSubscription = subscriptions.Items.FirstOrDefault(sub => sub.BillingType == BillingType.Usage && !sub.OfferId.StartsWith("MS-AZR")); if (modernAzureSubscription == null) { this.Context.ConsoleHelper.WriteColored("Customer doesn't have modern Azure plan, a new Azure plan will be purchased.", ConsoleColor.Yellow); } else { this.Context.ConsoleHelper.WriteColored($"Modern Azure Subscription Id: {modernAzureSubscription.Id}", ConsoleColor.Yellow); this.Context.ConsoleHelper.StartProgress("Retrieving Azure plan entitlements"); var azureEntitlments = partnerOperations.Customers.ById(customerId).Subscriptions.ById(modernAzureSubscription.Id).GetAzurePlanSubscriptionEntitlements(); this.Context.ConsoleHelper.StopProgress(); this.Context.ConsoleHelper.WriteObject(azureEntitlments, "Azure plan entitlements"); var azureEntitlementForOverage = azureEntitlments.Items.FirstOrDefault(e => e.FriendlyName == "Subscription 1"); azureEntitlementIdForOverage = azureEntitlementForOverage?.Id; if (azureEntitlementIdForOverage == null) { this.Context.ConsoleHelper.WriteColored("No existing modern Azure plan entitlement found, a new azure entitlement will be created.", ConsoleColor.Yellow); } else { azureEntitlementIdForOverage = this.Context.ConsoleHelper.ReadOptionalString( $"Enter Azure entitlement Id for overage (Leaving empty will consider 'Subscription 1' entitlement if exists or else it will create new)"); partnerId = this.Context.ConsoleHelper.ReadOptionalString($"Enter Reseller partnerId (Mpn Id) for overage if a reseller is associated with the azure plan"); } } this.Context.ConsoleHelper.StartProgress("Updating overage"); var overagePayload = new Overage { AzureEntitlementId = azureEntitlementIdForOverage, OverageEnabled = true, PartnerId = partnerId, }; var updatedOverage = partnerOperations.Customers.ById(customerId).Subscriptions.Overage.Put(overagePayload); this.Context.ConsoleHelper.StopProgress(); this.Context.ConsoleHelper.StartProgress("Retrieving overage"); var newOverage = partnerOperations.Customers.ById(customerId).Subscriptions.Overage.Get(); this.Context.ConsoleHelper.StopProgress(); this.Context.ConsoleHelper.WriteObject(newOverage, "Newly retrieved overage"); var newPhoneOverage = newOverage.Items.FirstOrDefault(o => o.Type == "PhoneServices"); if (!string.Equals(updatedOverage.AzureEntitlementId, newPhoneOverage?.AzureEntitlementId)) { this.Context.ConsoleHelper.WriteColored("The Overage update process hasn't completed yet.", ConsoleColor.Yellow); } }