public void Can_save_and_load_checkoutAttribute()
        {
            var ca = new CheckoutAttribute
            {
                Name = "Name 1",
                TextPrompt = "TextPrompt 1",
                IsRequired = true,
                ShippableProductRequired  = true,
                IsTaxExempt = true,
                TaxCategoryId = 1,
                AttributeControlType = AttributeControlType.Datepicker,
                DisplayOrder = 2
            };

            var fromDb = SaveAndLoadEntity(ca);
            fromDb.ShouldNotBeNull();
            fromDb.Name.ShouldEqual("Name 1");
            fromDb.TextPrompt.ShouldEqual("TextPrompt 1");
            fromDb.IsRequired.ShouldEqual(true);
            fromDb.ShippableProductRequired.ShouldEqual(true);
            fromDb.IsTaxExempt.ShouldEqual(true);
            fromDb.TaxCategoryId.ShouldEqual(1);
            fromDb.AttributeControlType.ShouldEqual(AttributeControlType.Datepicker);
            fromDb.DisplayOrder.ShouldEqual(2);
        }
コード例 #2
0
        public void Can_save_and_load_checkoutAttribute()
        {
            var ca = new CheckoutAttribute
            {
                Name = "Name 1",
                TextPrompt = "TextPrompt 1",
                IsRequired = true,
                ShippableProductRequired  = true,
                IsTaxExempt = true,
                TaxCategoryId = 1,
                AttributeControlType = AttributeControlType.Datepicker,
                DisplayOrder = 2,
                LimitedToStores = true,
                ValidationMinLength = 3,
                ValidationMaxLength = 4,
                ValidationFileAllowedExtensions = "ValidationFileAllowedExtensions 1",
                ValidationFileMaximumSize = 5,
            };

            var fromDb = SaveAndLoadEntity(ca);
            fromDb.ShouldNotBeNull();
            fromDb.Name.ShouldEqual("Name 1");
            fromDb.TextPrompt.ShouldEqual("TextPrompt 1");
            fromDb.IsRequired.ShouldEqual(true);
            fromDb.ShippableProductRequired.ShouldEqual(true);
            fromDb.IsTaxExempt.ShouldEqual(true);
            fromDb.TaxCategoryId.ShouldEqual(1);
            fromDb.AttributeControlType.ShouldEqual(AttributeControlType.Datepicker);
            fromDb.DisplayOrder.ShouldEqual(2);
            fromDb.ValidationMinLength.ShouldEqual(3);
            fromDb.ValidationMaxLength.ShouldEqual(4);
            fromDb.ValidationFileAllowedExtensions.ShouldEqual("ValidationFileAllowedExtensions 1");
            fromDb.ValidationFileMaximumSize.ShouldEqual(5);
            fromDb.LimitedToStores.ShouldEqual(true);
        }
コード例 #3
0
        /// <summary>
        /// Adds an attribute
        /// </summary>
        /// <param name="attributes">Attributes</param>
        /// <param name="ca">Checkout attribute</param>
        /// <param name="value">Value</param>
        /// <returns>Attributes</returns>
        public string AddCheckoutAttribute(string attributes, CheckoutAttribute ca, string value)
        {
            string result = string.Empty;
            try
            {
                var xmlDoc = new XmlDocument();
                if (String.IsNullOrEmpty(attributes))
                {
                    var _element1 = xmlDoc.CreateElement("Attributes");
                    xmlDoc.AppendChild(_element1);
                }
                else
                {
                    xmlDoc.LoadXml(attributes);
                }
                var rootElement = (XmlElement)xmlDoc.SelectSingleNode(@"//Attributes");

                XmlElement caElement = null;
                //find existing
                var nodeList1 = xmlDoc.SelectNodes(@"//Attributes/CheckoutAttribute");
                foreach (XmlNode node1 in nodeList1)
                {
                    if (node1.Attributes != null && node1.Attributes["ID"] != null)
                    {
                        string str1 = node1.Attributes["ID"].InnerText.Trim();
                        int id = 0;
                        if (int.TryParse(str1, out id))
                        {
                            if (id == ca.Id)
                            {
                                caElement = (XmlElement)node1;
                                break;
                            }
                        }
                    }
                }

                //create new one if not found
                if (caElement == null)
                {
                    caElement = xmlDoc.CreateElement("CheckoutAttribute");
                    caElement.SetAttribute("ID", ca.Id.ToString());
                    rootElement.AppendChild(caElement);
                }

                var cavElement = xmlDoc.CreateElement("CheckoutAttributeValue");
                caElement.AppendChild(cavElement);

                var cavVElement = xmlDoc.CreateElement("Value");
                cavVElement.InnerText = value;
                cavElement.AppendChild(cavVElement);

                result = xmlDoc.OuterXml;
            }
            catch (Exception exc)
            {
                Debug.Write(exc.ToString());
            }
            return result;
        }
コード例 #4
0
        public void Can_save_and_load_checkoutAttribute_with_values()
        {
            var ca = new CheckoutAttribute
            {
                Name = "Name 1",
                TextPrompt = "TextPrompt 1",
                IsRequired = true,
                ShippableProductRequired = true,
                IsTaxExempt = true,
                TaxCategoryId = 1,
                AttributeControlType = AttributeControlType.Datepicker,
                DisplayOrder = 2
            };
            ca.CheckoutAttributeValues.Add
                (
                    new CheckoutAttributeValue()
                    {
                        Name = "Name 2",
                        PriceAdjustment = 1,
                        WeightAdjustment = 2,
                        IsPreSelected = true,
                        DisplayOrder = 3,
                    }
                );
            var fromDb = SaveAndLoadEntity(ca);
            fromDb.ShouldNotBeNull();
            fromDb.Name.ShouldEqual("Name 1");

            fromDb.CheckoutAttributeValues.ShouldNotBeNull();
            (fromDb.CheckoutAttributeValues.Count == 1).ShouldBeTrue();
            fromDb.CheckoutAttributeValues.First().Name.ShouldEqual("Name 2");
        }
コード例 #5
0
        /// <summary>
        /// Deletes a checkout attribute
        /// </summary>
        /// <param name="checkoutAttribute">Checkout attribute</param>
        public virtual void DeleteCheckoutAttribute(CheckoutAttribute checkoutAttribute)
        {
            if (checkoutAttribute == null)
                throw new ArgumentNullException("checkoutAttribute");

            _checkoutAttributeRepository.Delete(checkoutAttribute);

            _cacheManager.RemoveByPattern(CHECKOUTATTRIBUTES_PATTERN_KEY);
            _cacheManager.RemoveByPattern(CHECKOUTATTRIBUTEVALUES_PATTERN_KEY);

            //event notification
            _eventPublisher.EntityDeleted(checkoutAttribute);
        }
コード例 #6
0
        protected virtual void UpdateAttributeLocales(CheckoutAttribute checkoutAttribute, CheckoutAttributeModel model)
        {
            foreach (var localized in model.Locales)
            {
                _localizedEntityService.SaveLocalizedValue(checkoutAttribute,
                                                               x => x.Name,
                                                               localized.Name,
                                                               localized.LanguageId);

                _localizedEntityService.SaveLocalizedValue(checkoutAttribute,
                                                               x => x.TextPrompt,
                                                               localized.TextPrompt,
                                                               localized.LanguageId);
            }
        }
コード例 #7
0
        protected virtual void PrepareStoresMappingModel(CheckoutAttributeModel model, CheckoutAttribute checkoutAttribute, bool excludeProperties)
        {
            if (model == null)
                throw new ArgumentNullException("model");

            if (!excludeProperties && checkoutAttribute != null)
                model.SelectedStoreIds = _storeMappingService.GetStoresIdsWithAccess(checkoutAttribute).ToList();

            var allStores = _storeService.GetAllStores();
            foreach (var store in allStores)
            {
                model.AvailableStores.Add(new SelectListItem
                {
                    Text = store.Name,
                    Value = store.Id.ToString(),
                    Selected = model.SelectedStoreIds.Contains(store.Id)
                });
            }
        }
コード例 #8
0
        protected virtual void PrepareStoresMappingModel(CheckoutAttributeModel model, CheckoutAttribute checkoutAttribute, bool excludeProperties)
        {
            if (model == null)
                throw new ArgumentNullException("model");

            model.AvailableStores = _storeService
                .GetAllStores()
                .Select(s => s.ToModel())
                .ToList();
            if (!excludeProperties)
            {
                if (checkoutAttribute != null)
                {
                    model.SelectedStoreIds = _storeMappingService.GetStoresIdsWithAccess(checkoutAttribute);
                }
            }
        }
コード例 #9
0
 protected virtual void SaveStoreMappings(CheckoutAttribute checkoutAttribute, CheckoutAttributeModel model)
 {
     var existingStoreMappings = _storeMappingService.GetStoreMappings(checkoutAttribute);
     var allStores = _storeService.GetAllStores();
     foreach (var store in allStores)
     {
         if (model.SelectedStoreIds != null && model.SelectedStoreIds.Contains(store.ID))
         {
             //new store
             if (existingStoreMappings.Count(sm => sm.StoreId == store.ID) == 0)
                 _storeMappingService.InsertStoreMapping(checkoutAttribute, store.ID);
         }
         else
         {
             //remove store
             var storeMappingToDelete = existingStoreMappings.FirstOrDefault(sm => sm.StoreId == store.ID);
             if (storeMappingToDelete != null)
                 _storeMappingService.DeleteStoreMapping(storeMappingToDelete);
         }
     }
 }
コード例 #10
0
 protected virtual void SaveConditionAttributes(CheckoutAttribute checkoutAttribute, CheckoutAttributeModel model)
 {
     string attributesXml = null;
     if (model.ConditionModel.EnableCondition)
     {
         var attribute = _checkoutAttributeService.GetCheckoutAttributeById(model.ConditionModel.SelectedAttributeId);
         if (attribute != null)
         {
             switch (attribute.AttributeControlType)
             {
                 case AttributeControlType.DropdownList:
                 case AttributeControlType.RadioList:
                 case AttributeControlType.ColorSquares:
                 case AttributeControlType.ImageSquares:
                     {
                         var selectedAttribute = model.ConditionModel.ConditionAttributes
                             .FirstOrDefault(x => x.Id == model.ConditionModel.SelectedAttributeId);
                         var selectedValue = selectedAttribute != null ? selectedAttribute.SelectedValueId : null;
                         if (!String.IsNullOrEmpty(selectedValue))
                             attributesXml = _checkoutAttributeParser.AddCheckoutAttribute(attributesXml, attribute, selectedValue);
                         else
                             //for conditions we should empty values save even when nothing is selected
                             //otherwise "attributesXml" will be empty
                             //hence we won't be able to find a selected attribute
                             attributesXml = _checkoutAttributeParser.AddCheckoutAttribute(attributesXml, attribute, string.Empty);
                     }
                     break;
                 case AttributeControlType.Checkboxes:
                     {
                         var selectedAttribute = model.ConditionModel.ConditionAttributes
                             .FirstOrDefault(x => x.Id == model.ConditionModel.SelectedAttributeId);
                         var selectedValues = selectedAttribute != null ? selectedAttribute.Values.Where(x => x.Selected).Select(x => x.Value) : null;
                         if (selectedValues.Any())
                             foreach (var value in selectedValues)
                                 attributesXml = _checkoutAttributeParser.AddCheckoutAttribute(attributesXml, attribute, value);
                         else
                             attributesXml = _checkoutAttributeParser.AddCheckoutAttribute(attributesXml, attribute, string.Empty);
                     }
                     break;
                 case AttributeControlType.ReadonlyCheckboxes:
                 case AttributeControlType.TextBox:
                 case AttributeControlType.MultilineTextbox:
                 case AttributeControlType.Datepicker:
                 case AttributeControlType.FileUpload:
                 default:
                     //these attribute types are not supported as conditions
                     break;
             }
         }
     }
     checkoutAttribute.ConditionAttributeXml = attributesXml;
 }
コード例 #11
0
        protected virtual void PrepareTaxCategories(CheckoutAttributeModel model, CheckoutAttribute checkoutAttribute, bool excludeProperties)
        {
            if (model == null)
                throw new ArgumentNullException("model");

            //tax categories
            var taxCategories = _taxCategoryService.GetAllTaxCategories();
            model.AvailableTaxCategories.Add(new SelectListItem { Text = "---", Value = "0" });
            foreach (var tc in taxCategories)
                model.AvailableTaxCategories.Add(new SelectListItem { Text = tc.Name, Value = tc.ID.ToString(), Selected = checkoutAttribute != null && !excludeProperties && tc.ID == checkoutAttribute.TaxCategoryId });
        }
コード例 #12
0
 protected virtual void InstallCheckoutAttributes()
 {
     var ca1 = new CheckoutAttribute
     {
         Id = 1,
         _id = ObjectId.GenerateNewId().ToString(),
         Name = "Gift wrapping",
         IsRequired = true,
         ShippableProductRequired = true,
         AttributeControlType = AttributeControlType.DropdownList,
         DisplayOrder = 1,
     };
     ca1.CheckoutAttributeValues.Add(new CheckoutAttributeValue
     {
         Id = 1,
         _id = ObjectId.GenerateNewId().ToString(),
         Name = "No",
         PriceAdjustment = 0,
         DisplayOrder = 1,
         IsPreSelected = true,
         CheckoutAttributeId = 1,
     });
     ca1.CheckoutAttributeValues.Add(new CheckoutAttributeValue
     {
         Id = 2,
         _id = ObjectId.GenerateNewId().ToString(),
         Name = "Yes",
         PriceAdjustment = 10,
         DisplayOrder = 2,
         CheckoutAttributeId = 1,
     });
     var checkoutAttributes = new List<CheckoutAttribute>
                         {
                             ca1,
                         };
     _checkoutAttributeRepository.Insert(checkoutAttributes);
 }
コード例 #13
0
 public static CheckoutAttribute ToEntity(this CheckoutAttributeModel model, CheckoutAttribute destination)
 {
     return Mapper.Map(model, destination);
 }
        public new void SetUp()
        {
            #region Test data

            //color (dropdownlist)
            ca1 = new CheckoutAttribute
            {
                Id = 1,
                Name= "Color",
                TextPrompt = "Select color:",
                IsRequired = true,
                AttributeControlType = AttributeControlType.DropdownList,
                DisplayOrder = 1,
            };
            cav1_1 = new CheckoutAttributeValue
            {
                Id = 11,
                Name = "Green",
                DisplayOrder = 1,
                CheckoutAttribute = ca1,
                CheckoutAttributeId = ca1.Id,
            };
            cav1_2 = new CheckoutAttributeValue
            {
                Id = 12,
                Name = "Red",
                DisplayOrder = 2,
                CheckoutAttribute = ca1,
                CheckoutAttributeId = ca1.Id,
            };
            ca1.CheckoutAttributeValues.Add(cav1_1);
            ca1.CheckoutAttributeValues.Add(cav1_2);

            //custom option (checkboxes)
            ca2 = new CheckoutAttribute
            {
                Id = 2,
                Name = "Custom option",
                TextPrompt = "Select custom option:",
                IsRequired = true,
                AttributeControlType = AttributeControlType.Checkboxes,
                DisplayOrder = 2,
            };
            cav2_1 = new CheckoutAttributeValue
            {
                Id = 21,
                Name = "Option 1",
                DisplayOrder = 1,
                CheckoutAttribute = ca2,
                CheckoutAttributeId = ca2.Id,
            };
            cav2_2 = new CheckoutAttributeValue
            {
                Id = 22,
                Name = "Option 2",
                DisplayOrder = 2,
                CheckoutAttribute = ca2,
                CheckoutAttributeId = ca2.Id,
            };
            ca2.CheckoutAttributeValues.Add(cav2_1);
            ca2.CheckoutAttributeValues.Add(cav2_2);

            //custom text
            ca3 = new CheckoutAttribute
            {
                Id = 3,
                Name = "Custom text",
                TextPrompt = "Enter custom text:",
                IsRequired = true,
                AttributeControlType = AttributeControlType.MultilineTextbox,
                DisplayOrder = 3,
            };

            #endregion

            _checkoutAttributeRepo = MockRepository.GenerateMock<IRepository<CheckoutAttribute>>();
            _checkoutAttributeRepo.Expect(x => x.Table).Return(new List<CheckoutAttribute> { ca1, ca2, ca3 }.AsQueryable());
            _checkoutAttributeRepo.Expect(x => x.GetById(ca1.Id)).Return(ca1);
            _checkoutAttributeRepo.Expect(x => x.GetById(ca2.Id)).Return(ca2);
            _checkoutAttributeRepo.Expect(x => x.GetById(ca3.Id)).Return(ca3);

            _checkoutAttributeValueRepo = MockRepository.GenerateMock<IRepository<CheckoutAttributeValue>>();
            _checkoutAttributeValueRepo.Expect(x => x.Table).Return(new List<CheckoutAttributeValue> { cav1_1, cav1_2, cav2_1, cav2_2 }.AsQueryable());
            _checkoutAttributeValueRepo.Expect(x => x.GetById(cav1_1.Id)).Return(cav1_1);
            _checkoutAttributeValueRepo.Expect(x => x.GetById(cav1_2.Id)).Return(cav1_2);
            _checkoutAttributeValueRepo.Expect(x => x.GetById(cav2_1.Id)).Return(cav2_1);
            _checkoutAttributeValueRepo.Expect(x => x.GetById(cav2_2.Id)).Return(cav2_2);

            var cacheManager = new NopNullCache();

            _storeMappingService = MockRepository.GenerateMock<IStoreMappingService>();

            _eventPublisher = MockRepository.GenerateMock<IEventPublisher>();
            _eventPublisher.Expect(x => x.Publish(Arg<object>.Is.Anything));

            _checkoutAttributeService = new CheckoutAttributeService(cacheManager,
                _checkoutAttributeRepo,
                _checkoutAttributeValueRepo,
                _storeMappingService,
                _eventPublisher);

            _checkoutAttributeParser = new CheckoutAttributeParser(_checkoutAttributeService);

            var workingLanguage = new Language();
            _workContext = MockRepository.GenerateMock<IWorkContext>();
            _workContext.Expect(x => x.WorkingLanguage).Return(workingLanguage);
            _currencyService = MockRepository.GenerateMock<ICurrencyService>();
            _taxService = MockRepository.GenerateMock<ITaxService>();
            _priceFormatter = MockRepository.GenerateMock<IPriceFormatter>();
            _downloadService = MockRepository.GenerateMock<IDownloadService>();
            _webHelper = MockRepository.GenerateMock<IWebHelper>();

            _checkoutAttributeFormatter = new CheckoutAttributeFormatter(_workContext,
                _checkoutAttributeService,
                _checkoutAttributeParser,
                _currencyService,
                _taxService,
                _priceFormatter,
                _downloadService,
                _webHelper);
        }
コード例 #15
0
        /// <summary>
        /// Check whether condition of some attribute is met (if specified). Return "null" if not condition is specified
        /// </summary>
        /// <param name="attribute">Checkout attribute</param>
        /// <param name="selectedAttributesXml">Selected attributes (XML format)</param>
        /// <returns>Result</returns>
        public virtual bool? IsConditionMet(CheckoutAttribute attribute, string selectedAttributesXml)
        {
            if (attribute == null)
                throw new ArgumentNullException("attribute");

            var conditionAttributeXml = attribute.ConditionAttributeXml;
            if (String.IsNullOrEmpty(conditionAttributeXml))
                //no condition
                return null;

            //load an attribute this one depends on
            var dependOnAttribute = ParseCheckoutAttributes(conditionAttributeXml).FirstOrDefault();
            if (dependOnAttribute == null)
                return true;

            var valuesThatShouldBeSelected = ParseValues(conditionAttributeXml, dependOnAttribute.Id)
                //a workaround here:
                //ConditionAttributeXml can contain "empty" values (nothing is selected)
                //but in other cases (like below) we do not store empty values
                //that's why we remove empty values here
                .Where(x => !String.IsNullOrEmpty(x))
                .ToList();
            var selectedValues = ParseValues(selectedAttributesXml, dependOnAttribute.Id);
            if (valuesThatShouldBeSelected.Count != selectedValues.Count)
                return false;

            //compare values
            var allFound = true;
            foreach (var t1 in valuesThatShouldBeSelected)
            {
                bool found = false;
                foreach (var t2 in selectedValues)
                    if (t1 == t2)
                        found = true;
                if (!found)
                    allFound = false;
            }

            return allFound;
        }
コード例 #16
0
        protected virtual void PrepareConditionAttributes(CheckoutAttributeModel model, CheckoutAttribute checkoutAttribute)
        {
            if (model == null)
                throw new ArgumentNullException("model");

            //currenty any checkout attribute can have condition.
            model.ConditionAllowed = true;

            if (checkoutAttribute == null)
                return;

            var selectedAttribute = _checkoutAttributeParser.ParseCheckoutAttributes(checkoutAttribute.ConditionAttributeXml).FirstOrDefault();
            var selectedValues = _checkoutAttributeParser.ParseCheckoutAttributeValues(checkoutAttribute.ConditionAttributeXml);

            model.ConditionModel = new ConditionModel()
            {
                EnableCondition = !string.IsNullOrEmpty(checkoutAttribute.ConditionAttributeXml),
                SelectedAttributeId = selectedAttribute != null ? selectedAttribute.Id : 0,
                ConditionAttributes = _checkoutAttributeService.GetAllCheckoutAttributes()
                    //ignore this attribute and non-combinable attributes
                    .Where(x => x.Id != checkoutAttribute.Id && x.CanBeUsedAsCondition())
                    .Select(x =>
                        new AttributeConditionModel()
                        {
                            Id = x.Id,
                            Name = x.Name,
                            AttributeControlType = x.AttributeControlType,
                            Values = _checkoutAttributeService.GetCheckoutAttributeValues(x.Id)
                                .Select(v => new SelectListItem() { Text = v.Name, Value = v.Id.ToString(),
                                    Selected = selectedAttribute != null && selectedAttribute.Id == x.Id && selectedValues.Any(sv => sv.Id == v.Id) }).ToList()
                        }).ToList()
            };
        }
コード例 #17
0
 protected virtual void InstallCheckoutAttributes()
 {
     var ca1 = new CheckoutAttribute
     {
         Name = "Gift wrapping",
         IsRequired = true,
         ShippableProductRequired = true,
         AttributeControlType = AttributeControlType.DropdownList,
         DisplayOrder = 1,
     };
     ca1.CheckoutAttributeValues.Add(new CheckoutAttributeValue()
     {
         Name = "No",
         PriceAdjustment = 0,
         DisplayOrder = 1,
         IsPreSelected = true,
     });
     ca1.CheckoutAttributeValues.Add(new CheckoutAttributeValue()
     {
         Name = "Yes",
         PriceAdjustment = 10,
         DisplayOrder = 2,
     });
     var checkoutAttributes = new List<CheckoutAttribute>
                         {
                             ca1,
                         };
     checkoutAttributes.ForEach(ca => _checkoutAttributeRepository.Insert(ca));
 }
コード例 #18
0
        protected virtual List<LocalizedProperty> UpdateAttributeLocales(CheckoutAttribute checkoutAttribute, CheckoutAttributeModel model)
        {
            List<LocalizedProperty> localized = new List<LocalizedProperty>();
            foreach (var local in model.Locales)
            {

                if (!(String.IsNullOrEmpty(local.Name)))
                    localized.Add(new LocalizedProperty()
                    {
                        LanguageId = local.LanguageId,
                        LocaleKey = "Name",
                        LocaleValue = local.Name,
                        _id = ObjectId.GenerateNewId().ToString(),
                        Id = localized.Count > 0 ? localized.Max(x => x.Id) + 1 : 1,

                    });

                if (!(String.IsNullOrEmpty(local.TextPrompt)))
                    localized.Add(new LocalizedProperty()
                    {
                        LanguageId = local.LanguageId,
                        LocaleKey = "TextPrompt",
                        LocaleValue = local.TextPrompt,
                        _id = ObjectId.GenerateNewId().ToString(),
                        Id = localized.Count > 0 ? localized.Max(x => x.Id) + 1 : 1,
                    });

            }
            return localized;
        }
コード例 #19
0
        protected virtual void PrepareAclModel(CheckoutAttributeModel model, CheckoutAttribute checkoutAttribute, bool excludeProperties)
        {
            if (model == null)
                throw new ArgumentNullException("model");

            model.AvailableCustomerRoles = _customerService
                .GetAllCustomerRoles(true)
                .Select(cr => cr.ToModel())
                .ToList();
            if (!excludeProperties)
            {
                if (checkoutAttribute != null)
                {
                    model.SelectedCustomerRoleIds = checkoutAttribute.CustomerRoles.ToArray();
                }
            }
        }
コード例 #20
0
        /// <summary>
        /// Remove an attribute
        /// </summary>
        /// <param name="attributesXml">Attributes in XML format</param>
        /// <param name="attribute">Checkout attribute</param>
        /// <returns>Updated result (XML format)</returns>
        public virtual string RemoveCheckoutAttribute(string attributesXml, CheckoutAttribute attribute)
        {
            string result = string.Empty;
            try
            {
                var xmlDoc = new XmlDocument();
                if (String.IsNullOrEmpty(attributesXml))
                {
                    var element1 = xmlDoc.CreateElement("Attributes");
                    xmlDoc.AppendChild(element1);
                }
                else
                {
                    xmlDoc.LoadXml(attributesXml);
                }
                var rootElement = (XmlElement)xmlDoc.SelectSingleNode(@"//Attributes");

                XmlElement attributeElement = null;
                //find existing
                var nodeList1 = xmlDoc.SelectNodes(@"//Attributes/CheckoutAttribute");
                foreach (XmlNode node1 in nodeList1)
                {
                    if (node1.Attributes != null && node1.Attributes["ID"] != null)
                    {
                        string str1 = node1.Attributes["ID"].InnerText.Trim();
                        int id;
                        if (int.TryParse(str1, out id))
                        {
                            if (id == attribute.Id)
                            {
                                attributeElement = (XmlElement)node1;
                                break;
                            }
                        }
                    }
                }

                //found
                if (attributeElement != null)
                {
                    rootElement.RemoveChild(attributeElement);
                }

                result = xmlDoc.OuterXml;
            }
            catch (Exception exc)
            {
                Debug.Write(exc.ToString());
            }
            return result;
        }