/// <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> /// 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(); }
/// <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> /// 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> /// 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); }
/// <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; }
/// <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(); }
/// <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> /// 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; }
/// <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); }