public void Exercise_9_2_Add_New_Attribute_Extra()
        {
            //Once again, we'll be using a Product Attribute resource
            var productAttributeResource = new Mozu.Api.Resources.Commerce.Catalog.Admin.Attributedefinition.AttributeResource(_apiContext);

            /*
             * We use a contract to declare an empty Product Attribute that we will populate with our data and then send via the API.
             *
             * Contracts define the data model that each object adheres to -- each contract has different required fields.
             * The API documentation is useful for viewing some required fields, but trial and error is needed in some cases as well.
             *
             * We viewed the Product Attribute model in Exercise 9.1, but here I'll define out the required fields for creating a new Attribute.
             *
             * newAttribute.AdminName -- string
             * newAttribute.AttributeCode -- string
             * newAttribute.DataType -- string (Types include "String", "ProductCode", and "Number"
             *                       --          Not all combinations of DataType and InputType are valid)
             * newAttribute.InputType -- string (Types include "List", "TextBox", "TextArea", "Yes/No", and "Date";
             *                        --         Depending on the type you choose, other fields may be required)
             *
             * (One of these Characteristics must be true)
             * newAttribute.isExtra -- bool
             * newAttribute.isOption -- bool
             * newAttribute.isProperty -- bool
             *
             * newAttribute.ValueType -- string (Types include "Predefined", "AdminEntered", and "ShopperEntered"
             *                        --          "Predefined" cannot be used when creating a new attribute and exist only on attributes included with Mozu
             *                        --          Use "AdminEntered" or "ShopperEntered" to tell Mozu who sets this attribute.
             *
             * You may encounter this error when creating Attributes:
             * "Attribute must have a valid configuration for an Attribute Type Rule.
             * The combination of the attribute's values if it is an option, extra, or property
             * for the selected data type, input type, and value type is invalid."
             *
             * To solve for this error, continue to try changing the DataType, InputType, or Characteristics.
             *
             */
            var newAttribute = new Mozu.Api.Contracts.ProductAdmin.Attribute()
            {
                //A name used solely within Mozu Admin
                AdminName = "monogram",

                //Used to uniquely identify an Attribute -- Mozu creates the AttributeFQN by adding "tenant~" to the AttributeCode
                //It's best practice to use lowercase for the AttributeCode
                AttributeCode = "monogram",

                //Defines the data entered by either Admin or Shopper users
                DataType = "String",

                //Defines the input form
                InputType = "TextBox",

                //Sets the Characteristic of the Attribute
                IsExtra = true,

                //Another contract -- AttributeLocalizedContent allows you to add a shopper-facing label
                Content = new Mozu.Api.Contracts.ProductAdmin.AttributeLocalizedContent()
                {
                    Name = "Monogram"
                },

                //Defines how the Attribute if an Admin or Shopper enters -- allows Shoppers to configure products with custom input.
                ValueType = "ShopperEntered"
            };

            //Add Your Code:
            //Create new attribute

            //Best Practice Tip:
            //Check if the attribute already exists before adding a new attribute.
            //The responseFields parameter allows you to choose which particular fields the Mozu API will return.
            var existingAttributes = productAttributeResource.GetAttributesAsync(filter: string.Format("AttributeCode sw '{0}'", newAttribute.AttributeCode), responseFields: "AttributeFQN").Result;

            //Verify that the attribute doesn't already exist by checking the TotalCount.
            if (existingAttributes.TotalCount == 0)
            {
                //Creating a new attribute returns an Attribute object if successful
                var resultingAttribute = productAttributeResource.AddAttributeAsync(newAttribute).Result;

                //Add Your Code:
                //Update the attribute search settings
                //Create the settings in your local model
                resultingAttribute.SearchSettings = new Mozu.Api.Contracts.ProductAdmin.AttributeSearchSettings()
                {
                    SearchableInAdmin      = true,
                    SearchableInStorefront = true,
                    SearchDisplayValue     = true
                };

                //And update the attribute via the API -- the responseField allows you to only return the AttributeFQN
                //For later use, requests like GetAttributeAsync require the AttributeFQN
                var resultingUpdatedAttribute = productAttributeResource.UpdateAttributeAsync(resultingAttribute, resultingAttribute.AttributeFQN, responseFields: "AttributeFQN").Result;
            }

            //Alternatively, you can use a try/catch block to handle errors returned from the Mozu API:
            try
            {
                var resultingAttribute = productAttributeResource.AddAttributeAsync(newAttribute).Result;
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine(e.Message);
                System.Diagnostics.Debug.WriteLine(e.InnerException.Message);
            }
        }
        public void Exercise_9_3_Add_Attributes()
        {
            //Another usage of a ProductAttributeResource
            var productAttributeResource = new Mozu.Api.Resources.Commerce.Catalog.Admin.Attributedefinition.AttributeResource(_apiContext);

            //We create a new attribute using a Contract just like in the previous exercise
            var newAttribute = new Mozu.Api.Contracts.ProductAdmin.Attribute()
            {
                AdminName     = "purse-size",
                AttributeCode = "purse-size",
                DataType      = "String",
                InputType     = "List",
                IsOption      = true,
                Content       = new Mozu.Api.Contracts.ProductAdmin.AttributeLocalizedContent()
                {
                    Name = "Purse Size"
                },
                ValueType        = "Predefined",
                VocabularyValues = new List <Mozu.Api.Contracts.ProductAdmin.AttributeVocabularyValue>()
                {
                    //Since this is an Option attribute, we must add VocabularyValues.
                    //Here, we can add one Value at a time
                    new Mozu.Api.Contracts.ProductAdmin.AttributeVocabularyValue()
                    {
                        Value   = "Petite",
                        Content = new Mozu.Api.Contracts.ProductAdmin.AttributeVocabularyValueLocalizedContent()
                        {
                            LocaleCode  = "en-US",
                            StringValue = "Petite"
                        }
                    }
                }
            };

            //Or, we can automate the process a bit with a collection of sizes that we then iterate over.
            var sizes = "Classic|Alta".Split('|');

            foreach (var size in sizes)
            {
                newAttribute.VocabularyValues.Add(new Mozu.Api.Contracts.ProductAdmin.AttributeVocabularyValue()
                {
                    Value   = size,
                    Content = new Mozu.Api.Contracts.ProductAdmin.AttributeVocabularyValueLocalizedContent()
                    {
                        LocaleCode  = "en-US",
                        StringValue = size
                    }
                });
            }

            //Add Your Code:
            //Check if attribute already exists, return back only the attributeFQN
            var existingAttributes = productAttributeResource.GetAttributesAsync(filter: string.Format("AttributeCode sw '{0}'", newAttribute.AttributeCode), responseFields: "AttributeFQN").Result;

            //Verify that the attribute doesn't exist
            if (existingAttributes.TotalCount == 0)
            {
                //Add Your Code: Add New Attribute
                var createdAttribute = productAttributeResource.AddAttributeAsync(newAttribute).Result;
            }
        }
        public void Exercise_9_2_Add_New_Attribute_Extra()
        {
            //Once again, we'll be using a Product Attribute resource
            var productAttributeResource = new Mozu.Api.Resources.Commerce.Catalog.Admin.Attributedefinition.AttributeResource(_apiContext);

            /*
             * We use a contract to declare an empty Product Attribute that we will populate with our data and then send via the API.
             *
             * Contracts define the data model that each object adheres to -- each contract has different required fields.
             * The API documentation is useful for viewing some required fields, but trial and error is needed in some cases as well.
             *
             * We viewed the Product Attribute model in Exercise 9.1, but here I'll define out the required fields for creating a new Attribute.
             *
             * newAttribute.AdminName -- string
             * newAttribute.AttributeCode -- string
             * newAttribute.DataType -- string (Types include "String", "ProductCode", and "Number"
             *                       --          Not all combinations of DataType and InputType are valid)
             * newAttribute.InputType -- string (Types include "List", "TextBox", "TextArea", "Yes/No", and "Date";
             *                        --         Depending on the type you choose, other fields may be required)
             *
             * (One of these Characteristics must be true)
             * newAttribute.isExtra -- bool
             * newAttribute.isOption -- bool
             * newAttribute.isProperty -- bool
             *
             * newAttribute.ValueType -- string (Types include "Predefined", "AdminEntered", and "ShopperEntered"
             *                        --          "Predefined" cannot be used when creating a new attribute and exist only on attributes included with Mozu
             *                        --          Use "AdminEntered" or "ShopperEntered" to tell Mozu who sets this attribute.
             *
             * You may encounter this error when creating Attributes:
             * "Attribute must have a valid configuration for an Attribute Type Rule.
             * The combination of the attribute's values if it is an option, extra, or property
             * for the selected data type, input type, and value type is invalid."
             *
             * To solve for this error, continue to try changing the DataType, InputType, or Characteristics.
             *
             */
            var newAttribute = new Mozu.Api.Contracts.ProductAdmin.Attribute()
            {
                //A name used solely within Mozu Admin
                AdminName = "monogram",

                //Used to uniquely identify an Attribute -- Mozu creates the AttributeFQN by adding "tenant~" to the AttributeCode
                //It's best practice to use lowercase for the AttributeCode
                AttributeCode = "monogram",

                //Defines the data entered by either Admin or Shopper users
                DataType = "String",

                //Defines the input form
                InputType = "TextBox",

                //Sets the Characteristic of the Attribute
                IsExtra = true,

                //Another contract -- AttributeLocalizedContent allows you to add a shopper-facing label
                Content = new Mozu.Api.Contracts.ProductAdmin.AttributeLocalizedContent()
                {
                    Name = "Monogram"
                },

                //Defines how the Attribute if an Admin or Shopper enters -- allows Shoppers to configure products with custom input.
                ValueType = "ShopperEntered"
            };

            //Add Your Code:
            //Create new attribute

            //Best Practice Tip:
            //Check if the attribute already exists before adding a new attribute.
            //The responseFields parameter allows you to choose which particular fields the Mozu API will return.
            var existingAttributes = productAttributeResource.GetAttributesAsync(filter: string.Format("AttributeCode sw '{0}'", newAttribute.AttributeCode), responseFields: "AttributeFQN").Result;

            //Verify that the attribute doesn't already exist by checking the TotalCount.
            if (existingAttributes.TotalCount == 0)
            {
                //Creating a new attribute returns an Attribute object if successful
                var resultingAttribute = productAttributeResource.AddAttributeAsync(newAttribute).Result;

                //Add Your Code:
                //Update the attribute search settings
                //Create the settings in your local model
                resultingAttribute.SearchSettings = new Mozu.Api.Contracts.ProductAdmin.AttributeSearchSettings()
                {
                    SearchableInAdmin = true,
                    SearchableInStorefront = true,
                    SearchDisplayValue = true
                };

                //And update the attribute via the API -- the responseField allows you to only return the AttributeFQN
                //For later use, requests like GetAttributeAsync require the AttributeFQN
                var resultingUpdatedAttribute = productAttributeResource.UpdateAttributeAsync(resultingAttribute, resultingAttribute.AttributeFQN, responseFields: "AttributeFQN").Result;
            }

            //Alternatively, you can use a try/catch block to handle errors returned from the Mozu API:
            try
            {
                var resultingAttribute = productAttributeResource.AddAttributeAsync(newAttribute).Result;
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine(e.Message);
                System.Diagnostics.Debug.WriteLine(e.InnerException.Message);
            }
        }
        public void Exercise_9_3_Add_Attributes()
        {
            //Another usage of a ProductAttributeResource
            var productAttributeResource = new Mozu.Api.Resources.Commerce.Catalog.Admin.Attributedefinition.AttributeResource(_apiContext);

            //We create a new attribute using a Contract just like in the previous exercise
            var newAttribute = new Mozu.Api.Contracts.ProductAdmin.Attribute()
            {
                AdminName = "purse-size",
                AttributeCode = "purse-size",
                DataType = "String",
                InputType = "List",
                IsOption = true,
                Content = new Mozu.Api.Contracts.ProductAdmin.AttributeLocalizedContent()
                {
                    Name = "Purse Size"
                },
                ValueType = "Predefined",
                VocabularyValues = new List<Mozu.Api.Contracts.ProductAdmin.AttributeVocabularyValue>()
                {
                    //Since this is an Option attribute, we must add VocabularyValues.
                    //Here, we can add one Value at a time
                    new Mozu.Api.Contracts.ProductAdmin.AttributeVocabularyValue()
                    {
                        Value = "Petite",
                        Content = new Mozu.Api.Contracts.ProductAdmin.AttributeVocabularyValueLocalizedContent()
                        {
                            LocaleCode = "en-US",
                            StringValue = "Petite"
                        }
                    }
                }
            };

            //Or, we can automate the process a bit with a collection of sizes that we then iterate over.
            var sizes = "Classic|Alta".Split('|');

            foreach(var size in sizes)
            {
                newAttribute.VocabularyValues.Add(new Mozu.Api.Contracts.ProductAdmin.AttributeVocabularyValue()
                {
                    Value = size,
                    Content = new Mozu.Api.Contracts.ProductAdmin.AttributeVocabularyValueLocalizedContent()
                    {
                        LocaleCode = "en-US",
                        StringValue = size
                    }
                });
            }

            //Add Your Code:
            //Check if attribute already exists, return back only the attributeFQN
            var existingAttributes = productAttributeResource.GetAttributesAsync(filter: string.Format("AttributeCode sw '{0}'", newAttribute.AttributeCode), responseFields: "AttributeFQN").Result;

            //Verify that the attribute doesn't exist
            if (existingAttributes.TotalCount == 0)
            {
                //Add Your Code: Add New Attribute
                var createdAttribute = productAttributeResource.AddAttributeAsync(newAttribute).Result;
            }
        }