Exemple #1
0
        /// <summary>
        /// Adds a NEW child for <code>childDimension</code> under this node.
        /// </summary>
        /// <param name="childDimension">The <code>ProductDimension</code> for the
        /// new child</param>
        /// <returns>The newly created child node.</returns>
        public ProductPartitionNode AddChild(ProductDimension childDimension)
        {
            // Passing a productPartitionId = 0 is insignificant here.
            ProductPartitionNode newChild = new ProductPartitionNode(this, childDimension, 0,
                                                                     children.Comparer);

            return(AddChild(newChild));
        }
Exemple #2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ProductPartitionNode"/>
 /// class.
 /// </summary>
 /// <param name="parentNode">The parent node.</param>
 /// <param name="dimension">The product dimension that this node wraps.</param>
 /// <param name="productPartitionId">The product partition ID.</param>
 /// <param name="comparer">The comparer for comparing instances of this
 /// product dimension.</param>
 public ProductPartitionNode(ProductPartitionNode parentNode, ProductDimension dimension,
                             long productPartitionId, IEqualityComparer <ProductDimension> comparer)
 {
     this.parentNode         = parentNode;
     this.dimension          = dimension;
     this.children           = new Dictionary <ProductDimension, ProductPartitionNode>(comparer);
     this.productPartitionId = productPartitionId;
     this.nodeState          = new BiddableUnitState();
 }
Exemple #3
0
 /// <summary>
 /// Returns the child node with the specified ProductDimension.
 /// </summary>
 /// <param name="dimension">The product dimension.</param>
 /// <returns></returns>
 public ProductPartitionNode GetChild(ProductDimension dimension)
 {
     if (!HasChild(dimension))
     {
         throw new ArgumentException(string.Format(
                                         ShoppingMessages.NoChildNodeFoundForDimension, dimension));
     }
     return(children[dimension]);
 }
Exemple #4
0
 /// <summary>
 /// Removes the child with the specified dimension.
 /// </summary>
 /// <param name="childDimension">The child dimension.</param>
 /// <returns>This node.</returns>
 public ProductPartitionNode RemoveChild(ProductDimension childDimension)
 {
     if (!children.ContainsKey(childDimension))
     {
         throw new ArgumentException(string.Format(ShoppingMessages.ChildNodeDoesNotExist,
                                                   childDimension));
     }
     children.Remove(childDimension);
     return(this);
 }
Exemple #5
0
        /// <summary>
        /// Clones this instance.
        /// </summary>
        /// <returns>The new node.</returns>
        internal ProductPartitionNode Clone()
        {
            ProductDimension newDimension = null;

            if (this.Dimension != null)
            {
                newDimension = (ProductDimension)SerializationUtilities.CloneObject(
                    this.Dimension);
            }
            ProductPartitionNode newNode = new ProductPartitionNode(null, newDimension,
                                                                    this.ProductPartitionId, this.children.Comparer);

            newNode = CopyProperties(this, newNode);
            newNode.CloneChildrenFrom(this.Children);
            return(newNode);
        }
Exemple #6
0
        /// <summary>
        /// Deeply clones each child in <paramref name="children"/> and attaches it
        /// to the current node.
        /// </summary>
        /// <param name="children">The children to clone</param>
        /// <returns>The minimum product partition ID found within the subtrees
        /// under <paramref name="children"/>.</returns>
        private void CloneChildrenFrom(IEnumerable <ProductPartitionNode> children)
        {
            foreach (ProductPartitionNode childNode in children)
            {
                if (!this.IsSubdivision)
                {
                    this.AsSubdivision();
                }

                // Clone the child and add it to newParent's collection of children.
                ProductDimension newDimension = (ProductDimension)SerializationUtilities.CloneObject(
                    childNode.Dimension);
                ProductPartitionNode newChild = this.AddChild(newDimension);
                newChild = CopyProperties(childNode, newChild);

                newChild.CloneChildrenFrom(childNode.Children);
            }
        }
      /// <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 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);
            }
 public void UpdateDimension(string imageName, string description, IEnumerable <KeyValuePair <int, double> > dimensionValues)
 {
     ProductDimension = new ProductDimension(description, imageName, dimensionValues);
 }
        /// <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;
        }
Exemple #11
0
 /// <summary>
 /// Determines whether this node has a child with the specified dimension.
 /// </summary>
 /// <param name="dimension">The child dimension.</param>
 /// <returns>True, if the child node exists, false otherwise.</returns>
 public bool HasChild(ProductDimension dimension)
 {
     return(dimension != null?children.ContainsKey(dimension) : false);
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="ProductPartitionNode"/>
 /// class.
 /// </summary>
 /// <param name="parentNode">The parent node.</param>
 /// <param name="dimension">The product dimension that this node wraps.</param>
 /// <param name="productPartitionId">The product partition ID.</param>
 public ProductPartitionNode(ProductPartitionNode parentNode, ProductDimension dimension,
     long productPartitionId)
   : this(parentNode, dimension, productPartitionId,
     new ProductDimensionEqualityComparer()) {
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="ProductPartitionNode"/>
 /// class.
 /// </summary>
 /// <param name="parentNode">The parent node.</param>
 /// <param name="dimension">The product dimension that this node wraps.</param>
 /// <param name="productPartitionId">The product partition ID.</param>
 /// <param name="comparer">The comparer for comparing instances of this
 /// product dimension.</param>
 public ProductPartitionNode(ProductPartitionNode parentNode, ProductDimension dimension,
     long productPartitionId, IEqualityComparer<ProductDimension> comparer) {
   this.parentNode = parentNode;
   this.dimension = dimension;
   this.children = new Dictionary<ProductDimension, ProductPartitionNode>(comparer);
   this.productPartitionId = productPartitionId;
   this.nodeState = new BiddableUnitState();
 }
Exemple #14
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ProductPartitionNode"/>
 /// class.
 /// </summary>
 /// <param name="parentNode">The parent node.</param>
 /// <param name="dimension">The product dimension that this node wraps.</param>
 /// <param name="productPartitionId">The product partition ID.</param>
 public ProductPartitionNode(ProductPartitionNode parentNode, ProductDimension dimension,
                             long productPartitionId)
     : this(parentNode, dimension, productPartitionId,
            new ProductDimensionEqualityComparer())
 {
 }
Exemple #15
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);
        }
 /// <summary>
 /// Returns the child node with the specified ProductDimension.
 /// </summary>
 /// <param name="dimension">The product dimension.</param>
 /// <returns></returns>
 public ProductPartitionNode GetChild(ProductDimension dimension) {
   if (!HasChild(dimension)) {
     throw new ArgumentException(string.Format(
         ShoppingMessages.NoChildNodeFoundForDimension, dimension));
   }
   return children[dimension];
 }
 /// <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>
 /// <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)
 {
     return CreateCriterionForProductPartition(partitionId, parentPartitionId, caseValue,
       isUnit, isExcluded, 0);
 }
            /// <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>
 /// Removes the child with the specified dimension.
 /// </summary>
 /// <param name="childDimension">The child dimension.</param>
 /// <returns>This node.</returns>
 public ProductPartitionNode RemoveChild(ProductDimension childDimension) {
   if (!children.ContainsKey(childDimension)) {
     throw new ArgumentException(string.Format(ShoppingMessages.ChildNodeDoesNotExist,
         childDimension));
   }
   children.Remove(childDimension);
   return this;
 }
 /// <summary>
 /// Adds a NEW child for <code>childDimension</code> under this node.
 /// </summary>
 /// <param name="childDimension">The <code>ProductDimension</code> for the
 /// new child</param>
 /// <returns>The newly created child node.</returns>
 public ProductPartitionNode AddChild(ProductDimension childDimension) {
   // Passing a productPartitionId = 0 is insignificant here.
   ProductPartitionNode newChild = new ProductPartitionNode(this, childDimension, 0,
       children.Comparer);
   return AddChild(newChild);
 }
 /// <summary>
 /// Determines whether this node has a child with the specified dimension.
 /// </summary>
 /// <param name="dimension">The child dimension.</param>
 /// <returns>True, if the child node exists, false otherwise.</returns>
 public bool HasChild(ProductDimension dimension) {
   return dimension != null ? children.ContainsKey(dimension) : false;
 }
Exemple #23
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>
 /// <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)
 {
     return(CreateCriterionForProductPartition(partitionId, parentPartitionId, caseValue,
                                               isUnit, isExcluded, 0));
 }
            private static PagedResult <SimpleProduct> InsertProductPropertiesIntoProduct(PagedResult <SimpleProduct> products, PagedResult <ProductBehavior> productsBehavior, PagedResult <ProductPrice> productPrices, PagedResult <LinkedProductRelation> linkedProductRelations, PagedResult <SimpleProduct> linkedProducts, IEnumerable <ProductComponent> components, IEnumerable <ProductDimension> productDimensions, IEnumerable <ProductDimensionValue> dimensionValues)
            {
                // Creating a dictionary for product prices to avoid having to loop over all product prices while looping over products to populate values.
                Dictionary <long, ProductPrice> productPriceDictionary = productPrices.Results.ToDictionary(price => price.ProductId, price => price);

                foreach (var product in products.Results)
                {
                    var matchingBehaviors = productsBehavior.Results.Where(r => r.ProductId == product.RecordId);
                    var matchingLinkedProductRelations = linkedProductRelations.Results.Where(r => r.ProductId == product.RecordId).Distinct();

                    if (matchingLinkedProductRelations.Any())
                    {
                        foreach (var linkedProductRelation in matchingLinkedProductRelations)
                        {
                            var matchingProduct = linkedProducts.Results.Where(l => l.RecordId == linkedProductRelation.LinkedProductId && l.IsRemote == product.IsRemote).SingleOrDefault();

                            if (matchingProduct != null)
                            {
                                // Merge product with relation rule to generate linked product.
                                SimpleLinkedProduct linkedProduct = new SimpleLinkedProduct();
                                linkedProduct.AdjustedPrice        = matchingProduct.AdjustedPrice;
                                linkedProduct.BasePrice            = matchingProduct.BasePrice;
                                linkedProduct.Behavior             = matchingProduct.Behavior;
                                linkedProduct.DefaultUnitOfMeasure = linkedProductRelation.UnitOfMeasure;
                                linkedProduct.Description          = matchingProduct.Description;
                                linkedProduct.ExtensionProperties  = matchingProduct.ExtensionProperties;
                                linkedProduct.ItemId      = matchingProduct.ItemId;
                                linkedProduct.Name        = matchingProduct.Name;
                                linkedProduct.Price       = matchingProduct.Price;
                                linkedProduct.ProductType = matchingProduct.ProductType;
                                linkedProduct.Quantity    = linkedProductRelation.Quantity;
                                linkedProduct.RecordId    = matchingProduct.RecordId;
                                linkedProduct.Dimensions  = matchingProduct.Dimensions;

                                product.LinkedProducts.Add(linkedProduct);
                            }
                            else
                            {
                                RetailLogger.Log.CrtServicesLinkedProductNotFound(linkedProductRelation.LinkedProductId, product.RecordId, product.IsRemote);
                            }
                        }
                    }

                    if (matchingBehaviors.Count() == 1)
                    {
                        product.Behavior = matchingBehaviors.Single();
                    }
                    else
                    {
                        var ex = new InvalidOperationException(string.Format("Exactly one behavior should be found for a product. But, '{0}' behavior(s) were found for product with identifier '{1}'.", matchingBehaviors.Count(), product.RecordId));
                        RetailLogger.Log.CrtServicesInvalidNumberOfProductBehaviorsFound(product.RecordId, matchingBehaviors.Count(), ex);

                        throw ex;
                    }

                    if (product.ProductType == ProductType.KitVariant)
                    {
                        product.Components = components.Where(c => c.VariantProductId == product.RecordId).Distinct().ToList();

                        foreach (var component in product.Components)
                        {
                            var matchingBehaviorsForComponent = productsBehavior.Results.Where(b => b.ProductId == component.ProductId).Distinct();
                            var matchingDimensionValues       = dimensionValues.Where(p => p.ProductId == component.ProductId).ToList();
                            component.Dimensions = new List <ProductDimension>();

                            foreach (var dimensionValue in matchingDimensionValues)
                            {
                                var dimension = new ProductDimension()
                                {
                                    DimensionType  = dimensionValue.DimensionType,
                                    DimensionValue = dimensionValue
                                };

                                component.Dimensions.Add(dimension);
                            }

                            if (matchingBehaviorsForComponent.Count() == 1)
                            {
                                component.Behavior = matchingBehaviorsForComponent.Single();
                            }
                            else
                            {
                                var ex = new InvalidOperationException(string.Format("Exactly one behavior should be found for a product. But '{0}' behavior(s) were found for product component with identifier '{1}'.", matchingBehaviorsForComponent.Count(), product.RecordId));
                                RetailLogger.Log.CrtServicesInvalidNumberOfProductBehaviorsFound(product.RecordId, matchingBehaviorsForComponent.Count(), ex);

                                throw ex;
                            }
                        }
                    }

                    if (product.ProductType == ProductType.Master)
                    {
                        product.Dimensions = productDimensions.Where(p => p.ProductId == product.RecordId).ToList();
                    }

                    if (product.ProductType == ProductType.Variant || product.ProductType == ProductType.KitVariant)
                    {
                        var matchingDimensionValues = dimensionValues.Where(p => p.ProductId == product.RecordId).ToList();
                        product.Dimensions = new List <ProductDimension>();

                        foreach (var dimensionValue in matchingDimensionValues)
                        {
                            var dimension = new ProductDimension()
                            {
                                DimensionType  = dimensionValue.DimensionType,
                                DimensionValue = dimensionValue
                            };

                            product.Dimensions.Add(dimension);
                        }
                    }

                    ProductPrice productPrice;
                    if (productPriceDictionary.TryGetValue(product.RecordId, out productPrice))
                    {
                        product.SetPrice(productPrice);
                    }
                }

                return(products);
            }