public void TestAddChildToUnitFails() { Assert.True(rootNode.IsUnit, "Root should be a unit by default."); Assert.Throws <ArgumentException>(delegate() { rootNode.AddChild(ProductDimensions.CreateBrand("google")); }); }
private void RebuildMultiNodeTree() { // Clear out the tree. ProductPartitionNode rootNode = tree.Root.RemoveAllChildren().AsSubdivision(); long[] bids = new long[] { 2500000L, 1500000L, 1000000L }; String[] productTypeValues = new String[] { "shoes", "clothing", null }; for (int i = 0; i < productTypeValues.Length; i++) { rootNode.AddChild(ProductDimensions.CreateType(ProductDimensionType.PRODUCT_TYPE_L1, productTypeValues[i])).AsBiddableUnit().CpcBid = bids[i]; } Assert.DoesNotThrow(delegate() { tree = ExecuteTreeOperations(); }); }
public void TestChildNodeBasicFunctionality() { rootNode = rootNode.AsSubdivision(); Assert.False(rootNode.IsUnit, "Parent should not be a unit."); Assert.True(rootNode.IsSubdivision, "Parent should be a subdivision."); ProductBrand childDimension = ProductDimensions.CreateBrand("google"); ProductPartitionNode childNode = rootNode.AddChild(childDimension); Assert.AreSame(childDimension, childNode.Dimension, "Child node merely wraps the " + "underlying dimension node."); Assert.AreSame(rootNode, childNode.Parent, "child.GetParent should return parentNode."); Assert.That(childNode.ProductPartitionId == 0, "Partition ID is incorrect."); Assert.That(childNode.Children.Count() == 0, "ChildNode should not have any children."); Assert.True(childNode.IsUnit, "New node should be a unit node by default."); Assert.True(childNode.IsBiddableUnit, "New node should be a biddable unit node by default."); Assert.That(rootNode.HasChild(childDimension), "rootNode.HasChild should return true when " + "passed the dimension of the added child"); Assert.False(rootNode.HasChild(ProductDimensions.CreateBrand("xyz")), "rootNode.HasChild " + "should return false when passed a dimension for a nonexistent child"); Assert.False(rootNode.HasChild(null), "rootNode.HasChild should return false when passed " + "a dimension for a nonexistent child"); }
/// <summary> /// Takes a tree with product type L1 "shoes" SUBDIVISION and collapses that node to a UNIT. /// </summary> private void CollapseShoes() { tree.Root.GetChild( ProductDimensions.CreateType(ProductDimensionType.PRODUCT_TYPE_L1, "shoes")) .AsBiddableUnit().CpcBid = (1500000L); Assert.DoesNotThrow(delegate() { tree = ExecuteTreeOperations(); }); }
/// <summary> /// Takes a tree with product type L1 "clothing" and sets its bid. /// </summary> /// <param name="bid">The bid.</param> private void UpdateClothingBid(long bid) { tree.Root.GetChild(ProductDimensions.CreateType(ProductDimensionType.PRODUCT_TYPE_L1, "clothing")).AsBiddableUnit().CpcBid = bid; Assert.DoesNotThrow(delegate() { tree = ExecuteTreeOperations(); }); }
public void TestRemoveChildThatDoesNotExistFails() { rootNode = rootNode.AsSubdivision(); Assert.Throws <ArgumentException>(delegate() { rootNode.RemoveChild(ProductDimensions.CreateBrand("google")); }); }
/// <summary> /// Uses obsolete category Hardware > Flooring (5264193646140135688). This is expected to /// fail with the error {@code CriterionError.INVALID_PRODUCT_BIDDING_CATEGORY}. /// </summary> private void UseObsoleteCategory() { tree.Root.RemoveAllChildren(); ProductPartitionNode hardwareLevel1 = tree.Root.AsSubdivision() .AddChild(ProductDimensions.CreateBiddingCategory( ProductDimensionType.BIDDING_CATEGORY_L1, 1689639310991627077L)) .AsSubdivision(); hardwareLevel1 .AddChild(ProductDimensions.CreateBiddingCategory( ProductDimensionType.BIDDING_CATEGORY_L2, 5264193646140135688L)).CpcBid = 1000000L; hardwareLevel1 .AddChild( ProductDimensions.CreateBiddingCategory( ProductDimensionType.BIDDING_CATEGORY_L2)).AsExcludedUnit(); tree.Root.AddChild( ProductDimensions.CreateBiddingCategory( ProductDimensionType.BIDDING_CATEGORY_L1)) .AsExcludedUnit(); try { tree = ExecuteTreeOperations(); Assert.Fail("Did not throw CriterionError.INVALID_PRODUCT_BIDDING_CATEGORY"); } catch (AdWordsApiException e) { ApiError[] errors = (e.ApiException as ApiException).errors; Assert.That(errors != null && errors.Length == 1); Assert.That(errors[0] is CriterionError); Assert.That((errors[0] as CriterionError).reason == CriterionErrorReason.INVALID_PRODUCT_BIDDING_CATEGORY); } }
/// <summary> /// Removes product type L1 "shoes". /// </summary> private void RemoveShoes() { tree.Root.RemoveChild( ProductDimensions.CreateType(ProductDimensionType.PRODUCT_TYPE_L1, "shoes")); Assert.DoesNotThrow(delegate() { tree = ExecuteTreeOperations(); }); }
public void TestNavigation() { rootNode = rootNode.AsSubdivision(); ProductBrand brandGoogle = ProductDimensions.CreateBrand("google"); ProductBrand brandOther = ProductDimensions.CreateBrand(null); ProductCanonicalCondition conditionNew = ProductDimensions.CreateCanonicalCondition(ProductCanonicalConditionCondition.NEW); ProductCanonicalCondition conditionUsed = ProductDimensions.CreateCanonicalCondition(ProductCanonicalConditionCondition.USED); ProductCanonicalCondition conditionOther = ProductDimensions.CreateCanonicalCondition(); // Build up the brand = Google node under the root. ProductPartitionNode brandGoogleNode = rootNode.AddChild(brandGoogle).AsSubdivision(); brandGoogleNode.AddChild(conditionNew); brandGoogleNode.AddChild(conditionUsed); brandGoogleNode.AddChild(conditionOther); Assert.True(brandGoogleNode.HasChild(conditionNew), "HasChild should return true for existing child dimension."); Assert.AreSame(brandGoogleNode, brandGoogleNode.GetChild(conditionNew).Parent, "parent->GetChild->getParent should return parent."); Assert.True(brandGoogleNode.HasChild(conditionUsed), "HasChild should return true for existing child dimension."); Assert.AreSame(brandGoogleNode, brandGoogleNode.GetChild(conditionUsed).Parent, "parent->GetChild->getParent should return parent."); Assert.True(brandGoogleNode.HasChild(conditionOther), "HasChild should return true for existing child dimension."); Assert.AreSame(brandGoogleNode, brandGoogleNode.GetChild(conditionOther).Parent, "parent->GetChild->getParent should return parent."); // Build up the brand = null (other) node under the root. ProductPartitionNode brandOtherNode = rootNode.AddChild(brandOther).AsSubdivision(); brandOtherNode.AddChild(conditionNew); Assert.True(brandOtherNode.HasChild(conditionNew), "HasChild should return true for existing child dimension."); Assert.AreSame(brandOtherNode, brandOtherNode.GetChild(conditionNew).Parent, "parent->GetChild->getParent should return parent."); Assert.False(brandOtherNode.HasChild(conditionUsed), "HasChild should return false for nonexistent child dimension."); Assert.False(brandOtherNode.HasChild(conditionOther), "HasChild should return false for nonexistent child dimension."); brandOtherNode.AddChild(conditionOther); Assert.True(brandOtherNode.HasChild(conditionOther), "HasChild should return true for existing child dimension."); Assert.AreSame(brandOtherNode, brandOtherNode.GetChild(conditionOther).Parent, "parent->GetChild->getParent should return parent."); // Remove one of the children of brand = null. brandOtherNode.RemoveChild(conditionOther); Assert.False(brandOtherNode.HasChild(conditionOther), "HasChild should return false for a removed child dimension."); // Remove the rest of the children of brand = null. brandOtherNode.RemoveAllChildren(); Assert.False(brandOtherNode.HasChild(conditionNew), "HasChild should return false for any removed child dimension."); Assert.False(brandOtherNode.HasChild(conditionUsed), "HasChild should return false for any removed child dimension."); }
/// <summary> /// Creates a product partition tree. /// </summary> /// <param name="user">The AdWords user for which the product partition is created.</param> /// <param name="adGroupId">Ad group ID.</param> /// <returns>The product partition.</returns> private static ProductPartitionTree CreateProductPartition(AdWordsUser user, long adGroupId) { using (AdGroupCriterionService adGroupCriterionService = (AdGroupCriterionService)user.GetService(AdWordsService.v201809 .AdGroupCriterionService)) { // Build a new ProductPartitionTree using the ad group's current set of criteria. ProductPartitionTree partitionTree = ProductPartitionTree.DownloadAdGroupTree(user, adGroupId); Console.WriteLine("Original tree: {0}", partitionTree); // Clear out any existing criteria. ProductPartitionNode rootNode = partitionTree.Root.RemoveAllChildren(); // Make the root node a subdivision. rootNode = rootNode.AsSubdivision(); // Add a unit node for condition = NEW to include it. rootNode.AddChild( ProductDimensions.CreateCanonicalCondition(ProductCanonicalConditionCondition .NEW)); // Add a unit node for condition = USED to include it. rootNode.AddChild( ProductDimensions.CreateCanonicalCondition(ProductCanonicalConditionCondition .USED)); // Exclude everything else. rootNode.AddChild(ProductDimensions.CreateCanonicalCondition()).AsExcludedUnit(); // Make the mutate request, using the operations returned by the // ProductPartitionTree. AdGroupCriterionOperation[] mutateOperations = partitionTree.GetMutateOperations(); if (mutateOperations.Length == 0) { Console.WriteLine( "Skipping the mutate call because the original tree and the current " + "tree are logically identical."); } else { adGroupCriterionService.mutate(mutateOperations); } // The request was successful, so create a new ProductPartitionTree based on the // updated state of the ad group. partitionTree = ProductPartitionTree.DownloadAdGroupTree(user, adGroupId); return(partitionTree); } }
/// <summary> /// Takes a tree with: /// /// <pre> /// ROOT /// ... /// shoes /// new /// offerId=1 $1.00 /// offerId=2 $2.00 /// ... /// offerId=20 $20.00 /// other - excluded /// </pre> /// /// and changes it to: /// /// <pre> /// ROOT /// ... /// shoes /// new $1.25 /// other $0.50 /// </pre> /// </summary> private void CollapseNewShoes() { ProductPartitionNode shoesLevel1 = tree.Root.GetChild(ProductDimensions.CreateType( ProductDimensionType.PRODUCT_TYPE_L1, "shoes")); shoesLevel1.GetChild(ProductDimensions.CreateCanonicalCondition( ProductCanonicalConditionCondition.NEW)).AsBiddableUnit().CpcBid = 1250000L; shoesLevel1.GetChild(ProductDimensions.CreateCanonicalCondition()).AsBiddableUnit() .CpcBid = 500000L; Assert.DoesNotThrow(delegate() { tree = ExecuteTreeOperations(); }); }
public void TestAddChildThatExistsFails() { rootNode = rootNode.AsSubdivision(); rootNode.AddChild(ProductDimensions.CreateBrand("google")); // Add the same child again. The call should fail. Assert.Throws<ArgumentException>(delegate() { rootNode.AddChild(ProductDimensions.CreateBrand("google")); }); // Add the same child again, this time with a different case. // The call should fail. Assert.Throws<ArgumentException>(delegate() { rootNode.AddChild(ProductDimensions.CreateBrand("GOOGLE")); }); }
public void TestCreateMultiNodeTreeFromScratch() { ProductPartitionTree tree = ProductPartitionTree.CreateAdGroupTree(new List <AdGroupCriterion>()); ProductPartitionNode rootNode = tree.Root.AsSubdivision(); ProductPartitionNode brand1 = rootNode.AddChild(ProductDimensions.CreateBrand("google")) .AsSubdivision(); ProductPartitionNode brand1Offer1 = brand1.AddChild(ProductDimensions.CreateOfferId("A")); brand1Offer1.AsBiddableUnit().CpcBid = 1000000L; ProductPartitionNode brand1Offer2 = brand1.AddChild(ProductDimensions.CreateOfferId()).AsExcludedUnit(); ProductPartitionNode brand2 = rootNode.AddChild(ProductDimensions.CreateBrand()).AsExcludedUnit(); ProductPartitionNode[] nodes = new ProductPartitionNode[] { rootNode, brand1, brand1Offer1, brand1Offer2, brand2 }; AdGroupCriterionOperation[] mutateOperations = tree.GetMutateOperations(); for (int i = 0; i < nodes.Length; i++) { List <AdGroupCriterionOperation> nodeOperations = shoppingTestUtils.GetOperationsForNode(nodes[i], mutateOperations); Assert.That(nodeOperations.Count == 1); Assert.That(nodeOperations[0].@operator == Operator.ADD); ProductPartition partition = (ProductPartition)nodeOperations[0].operand.criterion; Assert.That(partition.id == nodes[i].ProductPartitionId); if (nodes[i].Parent == null) { Assert.That(partition.parentCriterionIdSpecified == false); } else { Assert.That(partition.parentCriterionId == nodes[i].Parent.ProductPartitionId); } Assert.That(partition.caseValue == nodes[i].Dimension); } }
public void TestCreateOfferId() { ProductOfferId productOfferIdA = new ProductOfferId() { value = "google" }; ProductOfferId productOfferIdB = ProductDimensions.CreateOfferId("google"); Assert.True(comparer.Equals(productOfferIdA, productOfferIdB)); ProductOfferId productOfferIdC = new ProductOfferId() { }; ProductOfferId productOfferIdD = ProductDimensions.CreateOfferId(); Assert.True(comparer.Equals(productOfferIdC, productOfferIdD)); }
public void TestCreateBrand() { ProductBrand brandA = new ProductBrand() { value = "google" }; ProductBrand brandB = ProductDimensions.CreateBrand("google"); Assert.True(comparer.Equals(brandA, brandB)); ProductBrand brandC = new ProductBrand() { }; ProductBrand brandD = ProductDimensions.CreateBrand(); Assert.True(comparer.Equals(brandC, brandD)); }
/// <summary> /// Takes a tree with product type L1 "shoes" UNIT and subdivides that node into UNITs: /// /// <pre> /// shoes /// new $1.00 /// refurbished $1.50 /// other - excluded /// </pre> /// </summary> private void SubdivideShoes() { ProductPartitionNode shoesLevel1 = tree.Root.GetChild(ProductDimensions.CreateType( ProductDimensionType.PRODUCT_TYPE_L1, "shoes")) .AsSubdivision(); shoesLevel1.AddChild(ProductDimensions.CreateCanonicalCondition( ProductCanonicalConditionCondition.NEW)).AsBiddableUnit().CpcBid = 1000000L; shoesLevel1.AddChild(ProductDimensions.CreateCanonicalCondition( ProductCanonicalConditionCondition.REFURBISHED)).AsBiddableUnit().CpcBid = 1500000L; shoesLevel1.AddChild(ProductDimensions.CreateCanonicalCondition()).AsExcludedUnit(); Assert.DoesNotThrow(delegate() { tree = ExecuteTreeOperations(); }); }
public void TestCreateCanonicalCondition() { ProductCanonicalCondition conditionA = new ProductCanonicalCondition() { condition = ProductCanonicalConditionCondition.NEW }; ProductCanonicalCondition conditionB = ProductDimensions.CreateCanonicalCondition(ProductCanonicalConditionCondition.NEW); Assert.True(comparer.Equals(conditionA, conditionB)); ProductCanonicalCondition conditionC = new ProductCanonicalCondition() { }; ProductCanonicalCondition conditionD = ProductDimensions.CreateCanonicalCondition(); Assert.True(comparer.Equals(conditionC, conditionD)); }
public void TestProductChannelExclusivityEquals() { ProductChannelExclusivity channelExclusivityA = new ProductChannelExclusivity() { channelExclusivity = ShoppingProductChannelExclusivity.MULTI_CHANNEL }; ProductChannelExclusivity channelExclusivityB = ProductDimensions.CreateChannelExclusivity( ShoppingProductChannelExclusivity.MULTI_CHANNEL); Assert.True(comparer.Equals(channelExclusivityA, channelExclusivityB)); ProductChannelExclusivity channelExclusivityC = new ProductChannelExclusivity() { }; ProductChannelExclusivity channelExclusivityD = ProductDimensions.CreateChannelExclusivity(); Assert.True(comparer.Equals(channelExclusivityC, channelExclusivityD)); }
public void TestProductTypeEquals() { ProductType productTypeA = new ProductType() { type = ProductDimensionType.BRAND, value = "google", }; ProductType productTypeB = ProductDimensions.CreateType(ProductDimensionType.BRAND, "google"); Assert.True(comparer.Equals(productTypeA, productTypeB)); ProductType productTypeC = new ProductType() { type = ProductDimensionType.BRAND, }; ProductType productTypeD = ProductDimensions.CreateType(ProductDimensionType.BRAND); Assert.True(comparer.Equals(productTypeC, productTypeD)); }
public void TestCreateBiddingCategory() { ProductBiddingCategory categoryA = new ProductBiddingCategory() { type = ProductDimensionType.BIDDING_CATEGORY_L1, value = 2L }; ProductBiddingCategory categoryB = ProductDimensions.CreateBiddingCategory( ProductDimensionType.BIDDING_CATEGORY_L1, 2L); Assert.True(comparer.Equals(categoryA, categoryB)); ProductBiddingCategory categoryC = new ProductBiddingCategory() { type = ProductDimensionType.BIDDING_CATEGORY_L1, }; ProductBiddingCategory categoryD = ProductDimensions.CreateBiddingCategory( ProductDimensionType.BIDDING_CATEGORY_L1); Assert.True(comparer.Equals(categoryC, categoryD)); }
public void TestCreateCustomAttribute() { ProductCustomAttribute customAttributeA = new ProductCustomAttribute() { type = ProductDimensionType.BIDDING_CATEGORY_L1, value = "google" }; ProductCustomAttribute customAttributeB = ProductDimensions.CreateCustomAttribute( ProductDimensionType.BIDDING_CATEGORY_L1, "google"); Assert.True(comparer.Equals(customAttributeA, customAttributeB)); ProductCustomAttribute customAttributeC = new ProductCustomAttribute() { type = ProductDimensionType.BIDDING_CATEGORY_L1, }; ProductCustomAttribute customAttributeD = ProductDimensions.CreateCustomAttribute( ProductDimensionType.BIDDING_CATEGORY_L1); Assert.True(comparer.Equals(customAttributeC, customAttributeD)); }
public void TestSetBidOnUnit() { rootNode = rootNode.AsSubdivision(); ProductBrand childDimension = ProductDimensions.CreateBrand("google"); ProductPartitionNode childNode = rootNode.AddChild(childDimension); Assert.That(childNode.CpcBidSpecified == false, "Bid should be null by default."); childNode.CpcBid = 1L; Assert.AreEqual(1L, childNode.CpcBid, "Bid does not reflect setBid."); Assert.True(childNode.IsBiddableUnit, "Node should be a biddable unit."); childNode = childNode.AsExcludedUnit(); Assert.True(childNode.IsExcludedUnit, "Node should be an excluded unit."); Assert.False(childNode.IsBiddableUnit, "Node should not be a biddable unit."); Assert.False(childNode.CpcBidSpecified, "Excluded unit should have a null bid"); // Set back to biddable. childNode = childNode.AsBiddableUnit(); Assert.True(childNode.IsBiddableUnit, "Node should be a biddable unit."); }
public void TestRemovedCriteriaIgnored() { AdGroupCriterion rootCriterion = ShoppingTestUtils.CreateCriterionForProductPartition( 1L, 0L, null, true, false); List <AdGroupCriterion> criteria = new List <AdGroupCriterion>(); criteria.Add(rootCriterion); // Create a criteria for a child node and set its UserStatus to REMOVED. ProductBrand brandGoogle = ProductDimensions.CreateBrand("google"); AdGroupCriterion removedCriterion = ShoppingTestUtils.CreateCriterionForProductPartition( 2L, 1L, brandGoogle, true, false); ((BiddableAdGroupCriterion)removedCriterion).userStatus = UserStatus.REMOVED; criteria.Add(removedCriterion); ProductPartitionTree tree = ProductPartitionTree.CreateAdGroupTree(criteria); Assert.False(tree.Root.HasChild(brandGoogle), "Brand = google criteria had status removed, but it is in the tree."); }
public void TestCreateUltimatelyEmptyTree() { ProductPartitionTree tree = ProductPartitionTree.CreateAdGroupTree(new List <AdGroupCriterion>()); ProductPartitionNode rootNode = tree.Root.AsSubdivision(); ProductPartitionNode brand1 = rootNode.AddChild(ProductDimensions.CreateBrand("google")) .AsSubdivision(); ProductPartitionNode offerNode = brand1.AddChild(ProductDimensions.CreateOfferId("A")); offerNode.AsBiddableUnit().CpcBid = 1000000L; brand1.AddChild(ProductDimensions.CreateOfferId()).AsExcludedUnit(); ProductPartitionNode brand2 = rootNode.AddChild(ProductDimensions.CreateBrand()).AsExcludedUnit(); // Now remove the two child nodes under the root and set the root back // to a UNIT. This should result in operations that simply create the // root node. rootNode.RemoveChild(brand1.Dimension); rootNode.RemoveChild(brand2.Dimension); rootNode = rootNode.AsBiddableUnit(); AdGroupCriterionOperation[] mutateOperations = tree.GetMutateOperations(); Assert.AreEqual(mutateOperations.Count(), 1, "Number of operations is incorrect."); AdGroupCriterionOperation operation = mutateOperations[0]; Assert.AreEqual(Operator.ADD, operation.@operator, "Should have a single operation to ADD the root node."); BiddableAdGroupCriterion adGroupCriterion = (BiddableAdGroupCriterion)operation.operand; Assert.Null(((ProductPartition)adGroupCriterion.criterion).caseValue, "Product dimension of operation's operand should be null."); Assert.True(adGroupCriterion.criterion.id < 0L, "Partition ID of the operand should be negative."); }
/// <summary> /// Subdivides the new shoes. /// </summary> /// Takes a tree with: /// <pre> /// ROOT /// ... /// shoes /// new some bid /// </pre> /// /// and changes it to: /// /// <pre> /// ROOT /// ... /// shoes /// new /// other offerId $1.00 /// offerId=2 $2.00 /// ... /// offerId=20 $20.00 /// </pre> private void SubdivideNewShoes() { ProductPartitionNode shoesLevel1 = tree.Root.GetChild(ProductDimensions.CreateType( ProductDimensionType.PRODUCT_TYPE_L1, "shoes")).AsSubdivision(); ProductPartitionNode newShoesLevel2 = shoesLevel1.GetChild( ProductDimensions.CreateCanonicalCondition(ProductCanonicalConditionCondition.NEW)) .AsSubdivision(); for (int i = 1; i <= 20; i++) { ProductOfferId offerId = ProductDimensions.CreateOfferId(); if (i > 1) { offerId.value = i.ToString(); } newShoesLevel2.AddChild(offerId).AsBiddableUnit().CpcBid = i * 1000000L; } Assert.DoesNotThrow(delegate() { tree = ExecuteTreeOperations(); }); }
public void Init() { CAMPAIGN_ID = utils.CreateShoppingCampaign(user, BiddingStrategyType.MANUAL_CPC); ADGROUP_ID = utils.CreateAdGroup(user, CAMPAIGN_ID); tree = ProductPartitionTree.CreateAdGroupTree(ADGROUP_ID, new List <AdGroupCriterion>()); ProductPartitionNode root = tree.Root.AsSubdivision(); ProductPartitionNode clothing = root.AddChild(ProductDimensions.CreateType( ProductDimensionType.PRODUCT_TYPE_L1, "clothing")); clothing.AsBiddableUnit().CpcBid = 200000; ProductPartitionNode shoes = root.AddChild(ProductDimensions.CreateType( ProductDimensionType.PRODUCT_TYPE_L1, "shoes")); shoes.AsBiddableUnit().CpcBid = 400000; ProductPartitionNode otherNode = root.AddChild(ProductDimensions.CreateType( ProductDimensionType.PRODUCT_TYPE_L1)); otherNode.AsBiddableUnit().CpcBid = 300000; tree = ExecuteTreeOperations(); }
/// <summary> /// Creates a tree of the form: /// /// <pre> /// ROOT /// ProductType Level1 shoes /// ProductType Level2 athletic shoes /// Condition new $2.50 /// Condition used $1.00 /// Other - exclude from bidding /// ProductType Level2 walking shoes /// Condition new $3.50 /// Condition used $1.25 /// Other $1.00 /// ProductType Level2 null (everything else) - exclude from bidding /// ProductType Level1 clothing /// ProductType Level2 winter clothing /// Condition new $1.00 /// Condition used $1.25 /// Other $1.50 /// ProductType Level2 summer clothing /// Condition new $1.10 /// Condition used $1.00 /// Other $1.25 /// ProductType Level2 null (everything else) /// Condition new $0.90 /// Condition used $0.85 /// Other $0.75 /// ProductType Level1 null (everything else) - exclude from bidding /// </pre> /// </summary> private void RebuildComplexTree() { // Clear out the tree. ProductPartitionNode rootNode = tree.Root.RemoveAllChildren().AsSubdivision(); ProductPartitionNode shoesLevel1 = rootNode.AddChild(ProductDimensions.CreateType( ProductDimensionType.PRODUCT_TYPE_L1, "shoes")).AsSubdivision(); ProductPartitionNode athleticShoesLevel2 = shoesLevel1.AddChild( ProductDimensions.CreateType(ProductDimensionType.PRODUCT_TYPE_L2, "athletic shoes")) .AsSubdivision(); athleticShoesLevel2.AddChild(ProductDimensions.CreateCanonicalCondition( ProductCanonicalConditionCondition.NEW)).AsBiddableUnit().CpcBid = 2500000L; athleticShoesLevel2.AddChild(ProductDimensions.CreateCanonicalCondition( ProductCanonicalConditionCondition.USED)).AsBiddableUnit().CpcBid = 1000000L; athleticShoesLevel2.AddChild(ProductDimensions.CreateCanonicalCondition()).AsExcludedUnit(); ProductPartitionNode walkingShoesLevel2 = shoesLevel1.AddChild( ProductDimensions.CreateType(ProductDimensionType.PRODUCT_TYPE_L2, "walking shoes")) .AsSubdivision(); walkingShoesLevel2.AddChild(ProductDimensions.CreateCanonicalCondition( ProductCanonicalConditionCondition.NEW)).AsBiddableUnit().CpcBid = 3500000L; walkingShoesLevel2.AddChild(ProductDimensions.CreateCanonicalCondition( ProductCanonicalConditionCondition.USED)).AsBiddableUnit().CpcBid = 1250000L; walkingShoesLevel2.AddChild(ProductDimensions.CreateCanonicalCondition()).AsBiddableUnit() .CpcBid = 1000000L; shoesLevel1.AddChild(ProductDimensions.CreateType(ProductDimensionType.PRODUCT_TYPE_L2)) .AsExcludedUnit(); ProductPartitionNode clothingLevel1 = rootNode.AddChild(ProductDimensions.CreateType( ProductDimensionType.PRODUCT_TYPE_L1, "clothing")).AsSubdivision(); ProductPartitionNode winterClothingLevel2 = clothingLevel1.AddChild( ProductDimensions.CreateType(ProductDimensionType.PRODUCT_TYPE_L2, "winter clothing")) .AsSubdivision(); winterClothingLevel2.AddChild(ProductDimensions.CreateCanonicalCondition( ProductCanonicalConditionCondition.NEW)).AsBiddableUnit().CpcBid = 1000000L; winterClothingLevel2.AddChild(ProductDimensions.CreateCanonicalCondition( ProductCanonicalConditionCondition.USED)).AsBiddableUnit().CpcBid = 1250000L; winterClothingLevel2.AddChild(ProductDimensions.CreateCanonicalCondition()).AsBiddableUnit() .CpcBid = 1500000L; ProductPartitionNode summerClothingLevel2 = clothingLevel1.AddChild( ProductDimensions.CreateType(ProductDimensionType.PRODUCT_TYPE_L2, "summer clothing")) .AsSubdivision(); summerClothingLevel2.AddChild(ProductDimensions.CreateCanonicalCondition( ProductCanonicalConditionCondition.NEW)).AsBiddableUnit().CpcBid = 1100000L; summerClothingLevel2.AddChild(ProductDimensions.CreateCanonicalCondition( ProductCanonicalConditionCondition.USED)).AsBiddableUnit().CpcBid = 1000000L; summerClothingLevel2.AddChild(ProductDimensions.CreateCanonicalCondition()).AsBiddableUnit() .CpcBid = 1250000L; ProductPartitionNode otherClothingLevel2 = clothingLevel1.AddChild( ProductDimensions.CreateType(ProductDimensionType.PRODUCT_TYPE_L2, null)) .AsSubdivision(); otherClothingLevel2.AddChild(ProductDimensions.CreateCanonicalCondition( ProductCanonicalConditionCondition.NEW)).AsBiddableUnit().CpcBid = 900000L; otherClothingLevel2.AddChild(ProductDimensions.CreateCanonicalCondition( ProductCanonicalConditionCondition.USED)).AsBiddableUnit().CpcBid = 850000L; otherClothingLevel2.AddChild(ProductDimensions.CreateCanonicalCondition()).AsBiddableUnit() .CpcBid = 750000L; rootNode.AddChild(ProductDimensions.CreateType(ProductDimensionType.PRODUCT_TYPE_L1, null)) .AsExcludedUnit(); Assert.DoesNotThrow(delegate() { tree = ExecuteTreeOperations(); }); }
/// <summary> /// Runs the code example. /// </summary> /// <param name="user">The AdWords user.</param> /// <param name="adGroupId">The ad group to which product partition is /// added.</param> public void Run(AdWordsUser user, long adGroupId) { using (AdGroupCriterionService adGroupCriterionService = (AdGroupCriterionService)user.GetService( AdWordsService.v201802.AdGroupCriterionService)) { // Build a new ProductPartitionTree using the ad group's current set of criteria. ProductPartitionTree partitionTree = ProductPartitionTree.DownloadAdGroupTree(user, adGroupId); Console.WriteLine("Original tree: {0}", partitionTree); // Clear out any existing criteria. ProductPartitionNode rootNode = partitionTree.Root.RemoveAllChildren(); // Make the root node a subdivision. rootNode = rootNode.AsSubdivision(); // Add a unit node for condition = NEW. ProductPartitionNode newConditionNode = rootNode.AddChild( ProductDimensions.CreateCanonicalCondition(ProductCanonicalConditionCondition.NEW)); newConditionNode.AsBiddableUnit().CpcBid = 200000; ProductPartitionNode usedConditionNode = rootNode.AddChild( ProductDimensions.CreateCanonicalCondition(ProductCanonicalConditionCondition.USED)); usedConditionNode.AsBiddableUnit().CpcBid = 100000; // Add a subdivision node for condition = null (everything else). ProductPartitionNode otherConditionNode = rootNode.AddChild(ProductDimensions.CreateCanonicalCondition()).AsSubdivision(); // Add a unit node under condition = null for brand = "CoolBrand". ProductPartitionNode coolBrandNode = otherConditionNode.AddChild( ProductDimensions.CreateBrand("CoolBrand")); coolBrandNode.AsBiddableUnit().CpcBid = 900000L; // Add a unit node under condition = null for brand = "CheapBrand". ProductPartitionNode cheapBrandNode = otherConditionNode.AddChild( ProductDimensions.CreateBrand("CheapBrand")); cheapBrandNode.AsBiddableUnit().CpcBid = 10000L; // Add a subdivision node under condition = null for brand = null (everything else). ProductPartitionNode otherBrandNode = otherConditionNode.AddChild( ProductDimensions.CreateBrand(null)).AsSubdivision(); // Add unit nodes under condition = null/brand = null. // The value for each bidding category is a fixed ID for a specific // category. You can retrieve IDs for categories from the ConstantDataService. // See the 'GetProductCategoryTaxonomy' example for more details. // Add a unit node under condition = null/brand = null for product type // level 1 = 'Luggage & Bags'. ProductPartitionNode luggageAndBagNode = otherBrandNode.AddChild( ProductDimensions.CreateBiddingCategory(ProductDimensionType.BIDDING_CATEGORY_L1, -5914235892932915235L)); luggageAndBagNode.AsBiddableUnit().CpcBid = 750000L; // Add a unit node under condition = null/brand = null for product type // level 1 = null (everything else). ProductPartitionNode everythingElseNode = otherBrandNode.AddChild( ProductDimensions.CreateBiddingCategory(ProductDimensionType.BIDDING_CATEGORY_L1)); everythingElseNode.AsBiddableUnit().CpcBid = 110000L; try { // Make the mutate request, using the operations returned by the ProductPartitionTree. AdGroupCriterionOperation[] mutateOperations = partitionTree.GetMutateOperations(); if (mutateOperations.Length == 0) { Console.WriteLine("Skipping the mutate call because the original tree and the " + "current tree are logically identical."); } else { adGroupCriterionService.mutate(mutateOperations); } // The request was successful, so create a new ProductPartitionTree based on the updated // state of the ad group. partitionTree = ProductPartitionTree.DownloadAdGroupTree(user, adGroupId); Console.WriteLine("Final tree: {0}", partitionTree); } catch (Exception e) { throw new System.ApplicationException("Failed to set shopping product partition.", e); } } }