Exemple #1
0
        /// <summary>
        /// Outputs the list of BulkAdGroupProductPartition which each contain an AdGroupCriterion, formatted as a tree.
        /// Each AdGroupCriterion must be either a BiddableAdGroupCriterion or NegativeAdGroupCriterion.
        /// </summary>
        /// <param name="adGroupCriterions">The list of BulkAdGroupProductPartition to output formatted as a tree.</param>
        private void OutputProductPartitions(IList <BulkAdGroupProductPartition> bulkAdGroupProductPartitions)
        {
            // Set up the tree for output

            Dictionary <long, List <BulkAdGroupProductPartition> > childBranches =
                new Dictionary <long, List <BulkAdGroupProductPartition> >();
            BulkAdGroupProductPartition treeRoot = null;

            foreach (var bulkAdGroupProductPartition in bulkAdGroupProductPartitions)
            {
                AdGroupCriterion adGroupCriterion = bulkAdGroupProductPartition.AdGroupCriterion;
                if (adGroupCriterion != null)
                {
                    ProductPartition partition = (ProductPartition)adGroupCriterion.Criterion;
                    childBranches[(long)(adGroupCriterion.Id)] = new List <BulkAdGroupProductPartition>();

                    // The product partition with ParentCriterionId set to null is the root node.
                    if (partition.ParentCriterionId != null)
                    {
                        childBranches[(long)(partition.ParentCriterionId)].Add(bulkAdGroupProductPartition);
                    }
                    else
                    {
                        treeRoot = bulkAdGroupProductPartition;
                    }
                }
            }

            // Outputs the tree root node and any children recursively
            OutputProductPartitionTree(treeRoot, childBranches, 0);
        }
        /// <summary>
        /// Displays the product partition tree.
        /// </summary>
        /// <param name="node">The root node.</param>
        /// <param name="children">The child node.</param>
        /// <param name="level">The tree level.</param>
        /// <param name="writer">The stream to write output to.</param>
        private void DisplayTree(ProductPartition node, Dictionary <long,
                                                                    List <ProductPartition> > children, int level, StringWriter writer)
        {
            // Recursively display a node and each of its children.
            object value = null;
            string type  = "";

            if (node.caseValue != null)
            {
                type = node.caseValue.ProductDimensionType;
                switch (type)
                {
                case "ProductCanonicalCondition":
                    value = (node.caseValue as ProductCanonicalCondition).condition.ToString();
                    break;

                case "ProductBiddingCategory":
                    value = (node.caseValue as ProductBiddingCategory).type.ToString() + "(" +
                            (node.caseValue as ProductBiddingCategory).value + ")";
                    break;

                default:
                    value = node.caseValue.GetType().GetProperty("value").GetValue(node.caseValue, null);
                    break;
                }
            }

            writer.WriteLine("{0}id: {1}, type: {2}, value: {3}", "".PadLeft(level, ' '), node.id,
                             type, value);
            foreach (ProductPartition childNode in children[node.id])
            {
                DisplayTree(childNode, children, level + 1, writer);
            }
        }
Exemple #3
0
        /// <summary>
        /// Constructs a <see cref="ProductPartition" /> criterion corresponding to
        /// the node.
        /// </summary>
        /// <returns>The <see cref="ProductPartition" /> node.</returns>
        internal ProductPartition GetCriterion()
        {
            ProductPartition partition = new ProductPartition();

            partition.id = this.ProductPartitionId;

            if (this.Parent != null)
            {
                partition.parentCriterionId = this.Parent.ProductPartitionId;
            }
            partition.caseValue     = this.Dimension;
            partition.partitionType = this.IsUnit ? ProductPartitionType.UNIT :
                                      ProductPartitionType.SUBDIVISION;
            return(partition);
        }
Exemple #4
0
        /// <summary>
        /// Creates the criterion for product partition.
        /// </summary>
        /// <param name="partitionId">The product partition ID.</param>
        /// <param name="parentPartitionId">The proudct partition ID for parent node.</param>
        /// <param name="caseValue">The case value.</param>
        /// <param name="isUnit">True, if the node is UNIT node, false otherwise.</param>
        /// <param name="isExcluded">True, if the node is EXCLUDE node, false otherwise.</param>
        /// <param name="bid">The bid to be set on a node, if it is UNIT.</param>
        /// <returns>An ad group criterion node for the product partition.</returns>
        internal static AdGroupCriterion CreateCriterionForProductPartition(long partitionId,
                                                                            long parentPartitionId, ProductDimension caseValue, bool isUnit, bool isExcluded,
                                                                            long bid)
        {
            AdGroupCriterion adGroupCriterion;
            ProductPartition partition = new ProductPartition()
            {
                id = partitionId,
                parentCriterionId = parentPartitionId,
                caseValue         = caseValue,
                partitionType     =
                    isUnit ? ProductPartitionType.UNIT : ProductPartitionType.SUBDIVISION
            };

            if (isExcluded)
            {
                NegativeAdGroupCriterion negative = new NegativeAdGroupCriterion();
                adGroupCriterion = negative;
            }
            else
            {
                BiddableAdGroupCriterion biddable = new BiddableAdGroupCriterion();
                biddable.userStatus = UserStatus.ENABLED;

                BiddingStrategyConfiguration biddingConfig = new BiddingStrategyConfiguration();
                if (isUnit && bid != 0)
                {
                    CpcBid cpcBid = new CpcBid()
                    {
                        bid = new Money()
                        {
                            microAmount = bid
                        },
                        cpcBidSource = BidSource.CRITERION
                    };
                    biddingConfig.bids = new Bids[]
                    {
                        cpcBid
                    };
                }

                biddable.biddingStrategyConfiguration = biddingConfig;
                adGroupCriterion = biddable;
            }

            adGroupCriterion.criterion = partition;
            return(adGroupCriterion);
        }
        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);
            }
        }
      /// <summary>
      /// Creates a subdivision node.
      /// </summary>
      /// <param name="parent">The node that should be this node's parent.
      /// </param>
      /// <param name="value">The value being paritioned on.</param>
      /// <returns>A new subdivision node.</returns>
      public ProductPartition CreateSubdivision(ProductPartition parent, ProductDimension value) {
        ProductPartition division = new ProductPartition();
        division.partitionType = ProductPartitionType.SUBDIVISION;
        division.id = this.nextId--;

        // The root node has neither a parent nor a value.
        if (parent != null) {
          division.parentCriterionId = parent.id;
          division.caseValue = value;
        }

        BiddableAdGroupCriterion criterion = new BiddableAdGroupCriterion();
        criterion.adGroupId = this.adGroupId;
        criterion.criterion = division;

        this.CreateAddOperation(criterion);
        return division;
      }
        /// <summary>
        /// Creates a map with key as the parent criterion ID and value as the list of child nodes.
        /// </summary>
        /// <param name="adGroupCriteria">The list of ad group criteria.</param>
        /// <returns>A criteria map.</returns>
        private static Dictionary <long, List <AdGroupCriterion> > CreateParentIdMap(
            List <AdGroupCriterion> adGroupCriteria)
        {
            PreconditionUtilities.CheckNotNull(adGroupCriteria, ShoppingMessages.CriteriaListNull);

            Dictionary <long, List <AdGroupCriterion> > parentIdMap =
                new Dictionary <long, List <AdGroupCriterion> >();

            foreach (AdGroupCriterion adGroupCriterion in adGroupCriteria)
            {
                PreconditionUtilities.CheckNotNull(adGroupCriterion.criterion,
                                                   ShoppingMessages.AdGroupCriterionNull);
                if (adGroupCriterion is BiddableAdGroupCriterion)
                {
                    BiddableAdGroupCriterion biddableCriterion =
                        (BiddableAdGroupCriterion)adGroupCriterion;

                    PreconditionUtilities.CheckState(biddableCriterion.userStatusSpecified,
                                                     string.Format(ShoppingMessages.UserStatusNotSpecified,
                                                                   biddableCriterion.criterion.id));

                    if (biddableCriterion.userStatus == UserStatus.REMOVED)
                    {
                        continue;
                    }
                }

                if (adGroupCriterion.criterion is ProductPartition)
                {
                    ProductPartition        partition = (ProductPartition)adGroupCriterion.criterion;
                    List <AdGroupCriterion> children  = null;
                    if (!parentIdMap.TryGetValue(partition.parentCriterionId, out children))
                    {
                        children = new List <AdGroupCriterion>();
                        parentIdMap[partition.parentCriterionId] = children;
                    }

                    children.Add(adGroupCriterion);
                }
            }

            return(parentIdMap);
        }
        /// <summary>
        /// Using the criteria in <paramref name="parentIdMap"/>, recursively adds
        /// all children under the partition ID of <paramref name="parentNode"/> to
        /// <paramref name="parentNode"/>.
        /// </summary>
        /// <param name="parentNode">The parent node.</param>
        /// <param name="parentIdMap">The multimap from parent partition ID to list
        /// of child criteria</param>
        private static void AddChildNodes(ProductPartitionNode parentNode,
                                          Dictionary <long, List <AdGroupCriterion> > parentIdMap)
        {
            List <AdGroupCriterion> childCriteria = null;

            if (parentIdMap.ContainsKey(parentNode.ProductPartitionId))
            {
                childCriteria = parentIdMap[parentNode.ProductPartitionId];
            }

            // no children, return.
            if (childCriteria == null || childCriteria.Count == 0)
            {
                return;
            }

            // Ensure that the parent is a subdivision.
            parentNode.AsSubdivision();

            foreach (AdGroupCriterion childCriterion in childCriteria)
            {
                ProductPartition     partition = (ProductPartition)childCriterion.criterion;
                ProductPartitionNode childNode = parentNode.AddChild(partition.caseValue);
                childNode.ProductPartitionId = partition.id;

                if (childCriterion is BiddableAdGroupCriterion)
                {
                    childNode = childNode.AsBiddableUnit();
                    Money cpcBidAmount = GetBid((BiddableAdGroupCriterion)childCriterion);
                    if (cpcBidAmount != null)
                    {
                        childNode.CpcBid = cpcBidAmount.microAmount;
                    }
                }
                else
                {
                    childNode = childNode.AsExcludedUnit();
                }

                AddChildNodes(childNode, parentIdMap);
            }
        }
            /// <summary>
            /// Creates the unit.
            /// </summary>
            /// <param name="parent">The node that should be this node's parent.
            /// </param>
            /// <param name="value">The value being paritioned on.</param>
            /// <param name="bidAmount">The amount to bid for matching products,
            /// in micros.</param>
            /// <param name="isNegative">True, if this is negative criterion, false
            /// otherwise.</param>
            /// <returns>A new unit node.</returns>
            public ProductPartition CreateUnit(ProductPartition parent, ProductDimension value,
                                               long bidAmount, bool isNegative)
            {
                ProductPartition unit = new ProductPartition();

                unit.partitionType = ProductPartitionType.UNIT;

                // The root node has neither a parent nor a value.
                if (parent != null)
                {
                    unit.parentCriterionId = parent.id;
                    unit.caseValue         = value;
                }

                AdGroupCriterion criterion;

                if (isNegative)
                {
                    criterion = new NegativeAdGroupCriterion();
                }
                else
                {
                    BiddingStrategyConfiguration biddingStrategyConfiguration =
                        new BiddingStrategyConfiguration();

                    CpcBid cpcBid = new CpcBid();
                    cpcBid.bid                        = new Money();
                    cpcBid.bid.microAmount            = bidAmount;
                    biddingStrategyConfiguration.bids = new Bids[] { cpcBid };

                    criterion = new BiddableAdGroupCriterion();
                    (criterion as BiddableAdGroupCriterion).biddingStrategyConfiguration =
                        biddingStrategyConfiguration;
                }

                criterion.adGroupId = this.adGroupId;
                criterion.criterion = unit;

                this.CreateAddOperation(criterion);

                return(unit);
            }
        /// <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)
        {
            // Get the AdGroupCriterionService.
            AdGroupCriterionService adGroupCriterionService =
                (AdGroupCriterionService)user.GetService(
                    AdWordsService.v201506.AdGroupCriterionService);

            ProductPartitionHelper helper = new ProductPartitionHelper(adGroupId);

            // The most trivial partition tree has only a unit node as the root:
            //   helper.createUnit(null, null, 100000);

            ProductPartition root = helper.CreateSubdivision(null, null);

            ProductCanonicalCondition newCondition = new ProductCanonicalCondition();

            newCondition.condition = ProductCanonicalConditionCondition.NEW;
            ProductPartition newPartition = helper.CreateUnit(root, newCondition, 200000, false);

            ProductCanonicalCondition usedCondition = new ProductCanonicalCondition();

            usedCondition.condition = ProductCanonicalConditionCondition.USED;
            ProductPartition usedPartition = helper.CreateUnit(root, usedCondition, 100000, false);

            ProductPartition otherCondition = helper.CreateSubdivision(root,
                                                                       new ProductCanonicalCondition());

            ProductBrand coolBrand = new ProductBrand();

            coolBrand.value = "CoolBrand";
            helper.CreateUnit(otherCondition, coolBrand, 900000, false);

            ProductBrand cheapBrand = new ProductBrand();

            cheapBrand.value = "CheapBrand";
            helper.CreateUnit(otherCondition, cheapBrand, 10000, false);

            ProductPartition otherBrand =
                helper.CreateSubdivision(otherCondition, new ProductBrand());

            // The value for the bidding category is a fixed ID for the 'Luggage & Bags'
            // category. You can retrieve IDs for categories from the ConstantDataService.
            // See the 'GetProductCategoryTaxonomy' example for more details.

            ProductBiddingCategory luggageAndBags = new ProductBiddingCategory();

            luggageAndBags.type  = ProductDimensionType.BIDDING_CATEGORY_L1;
            luggageAndBags.value = -5914235892932915235;
            helper.CreateUnit(otherBrand, luggageAndBags, 750000, false);

            ProductBiddingCategory everythingElse = new ProductBiddingCategory();

            everythingElse.type = ProductDimensionType.BIDDING_CATEGORY_L1;

            helper.CreateUnit(otherBrand, everythingElse, 110000, false);

            try {
                // Make the mutate request.
                AdGroupCriterionReturnValue retval = adGroupCriterionService.mutate(helper.Operations);

                Dictionary <long, List <ProductPartition> > children =
                    new Dictionary <long, List <ProductPartition> >();
                ProductPartition rootNode = null;
                // For each criterion, make an array containing each of its children
                // We always create the parent before the child, so we can rely on that here.
                foreach (AdGroupCriterion adGroupCriterion in retval.value)
                {
                    ProductPartition newCriterion = (ProductPartition)adGroupCriterion.criterion;
                    children[newCriterion.id] = new List <ProductPartition>();

                    if (newCriterion.parentCriterionIdSpecified)
                    {
                        children[newCriterion.parentCriterionId].Add(newCriterion);
                    }
                    else
                    {
                        rootNode = (ProductPartition)adGroupCriterion.criterion;
                    }
                }

                // Show the tree
                StringWriter writer = new StringWriter();
                DisplayTree(rootNode, children, 0, writer);
                Console.WriteLine(writer.ToString());
            } catch (Exception ex) {
                throw new System.ApplicationException("Failed to set shopping product partition.", ex);
            }
        }
 /// <summary>
 /// Outputs the ProductPartition.
 /// </summary>
 protected void OutputProductPartition(ProductPartition productPartition)
 {
     if (productPartition != null)
     {
         OutputStatusMessage(string.Format("ParentCriterionId: {0}", productPartition.ParentCriterionId));
         OutputStatusMessage(string.Format("PartitionType: {0}", productPartition.PartitionType));
         if (productPartition.Condition != null)
         {
             OutputStatusMessage(string.Format("Condition: "));
             OutputStatusMessage(string.Format("\tOperand: {0}", productPartition.Condition.Operand));
             OutputStatusMessage(string.Format("\tAttribute: {0}", productPartition.Condition.Attribute));
         }
     }
 }
            /// <summary>
            /// Creates the unit.
            /// </summary>
            /// <param name="parent">The node that should be this node's parent.
            /// </param>
            /// <param name="value">The value being paritioned on.</param>
            /// <param name="bidAmount">The amount to bid for matching products,
            /// in micros.</param>
            /// <param name="isNegative">True, if this is negative criterion, false
            /// otherwise.</param>
            /// <returns>A new unit node.</returns>
            public ProductPartition CreateUnit(ProductPartition parent, ProductDimension value,
          long bidAmount, bool isNegative)
            {
                ProductPartition unit = new ProductPartition();
                unit.partitionType = ProductPartitionType.UNIT;

                // The root node has neither a parent nor a value.
                if (parent != null) {
                  unit.parentCriterionId = parent.id;
                  unit.caseValue = value;
                }

                AdGroupCriterion criterion;

                if (isNegative) {
                  criterion = new NegativeAdGroupCriterion();
                } else {
                  BiddingStrategyConfiguration biddingStrategyConfiguration =
                  new BiddingStrategyConfiguration();

                  CpcBid cpcBid = new CpcBid();
                  cpcBid.bid = new Money();
                  cpcBid.bid.microAmount = bidAmount;
                  biddingStrategyConfiguration.bids = new Bids[] { cpcBid };

                  criterion = new BiddableAdGroupCriterion();
                  (criterion as BiddableAdGroupCriterion).biddingStrategyConfiguration =
                  biddingStrategyConfiguration;
                }

                criterion.adGroupId = this.adGroupId;
                criterion.criterion = unit;

                this.CreateAddOperation(criterion);

                return unit;
            }
            /// <summary>
            /// Creates a subdivision node.
            /// </summary>
            /// <param name="parent">The node that should be this node's parent.
            /// </param>
            /// <param name="value">The value being paritioned on.</param>
            /// <returns>A new subdivision node.</returns>
            public ProductPartition CreateSubdivision(ProductPartition parent, ProductDimension value)
            {
                ProductPartition division = new ProductPartition();
                division.partitionType = ProductPartitionType.SUBDIVISION;
                division.id = this.nextId--;

                // The root node has neither a parent nor a value.
                if (parent != null) {
                  division.parentCriterionId = parent.id;
                  division.caseValue = value;
                }

                BiddableAdGroupCriterion criterion = new BiddableAdGroupCriterion();
                criterion.adGroupId = this.adGroupId;
                criterion.criterion = division;

                this.CreateAddOperation(criterion);
                return division;
            }
        /// <summary>
        /// Displays the product partition tree.
        /// </summary>
        /// <param name="node">The root node.</param>
        /// <param name="children">The child node.</param>
        /// <param name="level">The tree level.</param>
        /// <param name="writer">The stream to write output to.</param>
        private void DisplayTree(ProductPartition node, Dictionary<long,
        List<ProductPartition>> children, int level, StringWriter writer)
        {
            // Recursively display a node and each of its children.
              object value = null;
              string type = "";

              if (node.caseValue != null) {
            type = node.caseValue.ProductDimensionType;
            switch (type) {
              case "ProductCanonicalCondition":
            value = (node.caseValue as ProductCanonicalCondition).condition.ToString();
            break;

              case "ProductBiddingCategory":
            value = (node.caseValue as ProductBiddingCategory).type.ToString() + "(" +
                (node.caseValue as ProductBiddingCategory).value + ")";
            break;

              default:
            value = node.caseValue.GetType().GetProperty("value").GetValue(node.caseValue, null);
            break;
            }
              }

              writer.WriteLine("{0}id: {1}, type: {2}, value: {3}", "".PadLeft(level, ' '), node.id,
              type, value);
              foreach (ProductPartition childNode in children[node.id]) {
            DisplayTree(childNode, children, level + 1, writer);
              }
        }
    /// <summary>
    /// Constructs a <see cref="ProductPartition" /> criterion corresponding to
    /// the node.
    /// </summary>
    /// <returns>The <see cref="ProductPartition" /> node.</returns>
    internal ProductPartition GetCriterion() {
      ProductPartition partition = new ProductPartition();
      partition.id = this.ProductPartitionId;

      if (this.Parent != null) {
        partition.parentCriterionId = this.Parent.ProductPartitionId;
      }
      partition.caseValue = this.Dimension;
      partition.partitionType = this.IsUnit ? ProductPartitionType.UNIT :
          ProductPartitionType.SUBDIVISION;
      return partition;
    }
        /// <summary>
        /// Creates the criterion for product partition.
        /// </summary>
        /// <param name="partitionId">The product partition ID.</param>
        /// <param name="parentPartitionId">The proudct partition ID for parent node.</param>
        /// <param name="caseValue">The case value.</param>
        /// <param name="isUnit">True, if the node is UNIT node, false otherwise.</param>
        /// <param name="isExcluded">True, if the node is EXCLUDE node, false otherwise.</param>
        /// <param name="bid">The bid to be set on a node, if it is UNIT.</param>
        /// <returns>An ad group criterion node for the product partition.</returns>
        internal static AdGroupCriterion CreateCriterionForProductPartition(long partitionId,
        long parentPartitionId, ProductDimension caseValue, bool isUnit, bool isExcluded,
        long bid)
        {
            AdGroupCriterion adGroupCriterion;
              ProductPartition partition = new ProductPartition() {
            id = partitionId,
            parentCriterionId = parentPartitionId,
            caseValue = caseValue,
            partitionType = isUnit ? ProductPartitionType.UNIT : ProductPartitionType.SUBDIVISION
              };

              if (isExcluded) {
            NegativeAdGroupCriterion negative = new NegativeAdGroupCriterion();
            adGroupCriterion = negative;
              } else {
            BiddableAdGroupCriterion biddable = new BiddableAdGroupCriterion();
            biddable.userStatus = UserStatus.ENABLED;

            BiddingStrategyConfiguration biddingConfig = new BiddingStrategyConfiguration();
            if (isUnit && bid != 0) {
              CpcBid cpcBid = new CpcBid() {
            bid = new Money() {
              microAmount = bid
            },
            cpcBidSource = BidSource.CRITERION
              };
              biddingConfig.bids = new Bids[] { cpcBid };
            }
            biddable.biddingStrategyConfiguration = biddingConfig;
            adGroupCriterion = biddable;
              }
              adGroupCriterion.criterion = partition;
              return adGroupCriterion;
        }