public void Setup()
 {
     china = new HierarchyDataObject { HierarchyType = GEOGRAPHY, Name = "China",CreatedDate = System.DateTime.Now };
     string serviceUri = @"/HierarchyService.svc/json/Save";
     string content = TestServicesHelper.GenerateJsonByType(china);
     string id = TestServicesHelper.GetResponse<HttpWebRequest>(serviceUri, userName, password, TestServicesHelper.PostDataByJsonWithContent, content,null).Replace("\"", "");
     china.Id = new Guid(id);
 }
        /// <summary>
        /// Create a new hierarchy data from detail panel and return its id.
        /// The method needs to create a new entity and set control values to its properties then persist it.
        /// </summary>
        /// <returns>returns the id of new created hierarchy data.</returns>
        public override string Create()
        {
            this.ValidateInput(Guid.Empty);

            HierarchyDataObject hierarchyDataObject = new HierarchyDataObject();
            hierarchyDataObject.ExtensionDataTypeId = this.ResolveExtensionDataTypeId();
            hierarchyDataObject.HierarchyType = authenticationContext.TempVariables["HierarchyType"] as string;

            if (this.TextBoxName != null)
                hierarchyDataObject.Name = this.TextBoxName.Text;

            if (this.ComboBoxParentHierarchyData != null)
                hierarchyDataObject.ParentHierarchyDataId = string.IsNullOrEmpty(this.ComboBoxParentHierarchyData.SelectedValue) ? (Guid?)null : new Guid(this.ComboBoxParentHierarchyData.SelectedValue);

            if (this.TextBoxDescription != null)
                hierarchyDataObject.Description = this.TextBoxDescription.Text;

            if (this.ExtensionDataForm != null)
                this.ExtensionDataForm.SetObjectPropertiesFromControlValues(hierarchyDataObject);

            hierarchyApi.Save(hierarchyDataObject);
            return hierarchyDataObject.HierarchyDataId.ToString();
        }
        /// <summary>
        /// Update an existed hierarchy data from detail panel.
        /// The method needs to load an existed entity by specified id and set control values to overwrite its original properties then persist it.
        /// </summary>
        /// <param name="entityId"></param>
        public override void Update(string entityId)
        {
            Guid hierarchyDataId = new Guid(entityId);
            this.ValidateInput(hierarchyDataId);
            HierarchyDataObject hierarchyDataObject = hierarchyApi.GetHierarchyData(hierarchyDataId);
            if (hierarchyDataObject == null)
                throw new ValidationException(Resources.InvalidHierarchyDataId);

            hierarchyDataObject = new HierarchyDataObject { HierarchyDataId = hierarchyDataId };
            hierarchyDataObject.ExtensionDataTypeId = this.ResolveExtensionDataTypeId();
            hierarchyDataObject.HierarchyType = authenticationContext.TempVariables["HierarchyType"] as string;

            if (this.TextBoxName != null)
                hierarchyDataObject.Name = this.TextBoxName.Text;

            if (this.ComboBoxParentHierarchyData != null)
                hierarchyDataObject.ParentHierarchyDataId = string.IsNullOrEmpty(this.ComboBoxParentHierarchyData.SelectedValue) ? (Guid?)null : new Guid(this.ComboBoxParentHierarchyData.SelectedValue);

            if (this.TextBoxDescription != null)
                hierarchyDataObject.Description = this.TextBoxDescription.Text;

            if (this.ExtensionDataForm != null)
                this.ExtensionDataForm.SetObjectPropertiesFromControlValues(hierarchyDataObject);

            hierarchyApi.Save(hierarchyDataObject);
        }
        private static HierarchyDataObject ResolveHierarchyDisplayName(HierarchyDataObject hierarchyDataObject, int hierarchyLevel)
        {
            if (hierarchyLevel <= 0) return hierarchyDataObject;

            string prefix = "";
            for (int i = 0; i < hierarchyLevel; i++)
                prefix += "--";

            HierarchyDataObject returnValue = hierarchyDataObject.Clone();
            returnValue.Name = string.Format(CultureInfo.InvariantCulture, "{0} {1}", prefix, hierarchyDataObject.Name);
            return returnValue;
        }
        public void HierarchyTreeStory()
        {
            _story = new Story("Save the Hierarchy data And Bind to Organization Type");

            _story.AsA("User")
            .IWant("Create Hierarchy Data")
            .SoThat("I can bind the Hierarchy to the object that have cascade relationship");

            _story.WithScenario("Save Hierarchy Data")
            .Given("a Hierarchy data which is new ", () =>
            {
                _HierarchyDataObject = new HierarchyDataObject()
                {
                    Code = "1111",
                    Description = "Sample",
                    HierarchyType = "Tree",
                    Name = "Root"
                };

                _HierarchyApi.Save(_HierarchyDataObject);
                createHierarchyIds.Add(_HierarchyDataObject.Id);
            })
            .And("create More than one Organization ", () =>
            {
                _OrganizationTypeObject1 = _Organutils.CreateOrganizationTypeOject("Root", "Inc");

                _OrganizationApi.Save(_OrganizationTypeObject1);
                createdOrganizationTypeIds.Add(_OrganizationTypeObject1.OrganizationTypeId);

                _OrganizationObject1 = _Organutils.CreateOrganizationObject(_OrganizationTypeObject1.OrganizationTypeId, "Tim", "sh");
                _OrganizationObject2 = _Organutils.CreateOrganizationObject(_OrganizationTypeObject1.OrganizationTypeId, "Euge", "sc");

                _OrganizationApi.Save(_OrganizationObject1);
                _OrganizationApi.Save(_OrganizationObject2);

                createdOrganizationIds.Add(_OrganizationObject1.OrganizationId);
                createdOrganizationIds.Add(_OrganizationObject2.OrganizationId);
            })
            .When("Have the Hierarchy Data", () =>
            {
                _HierarchyDataObject1 = _HierarchyApi.GetHierarchyData(_HierarchyDataObject.Id);
                _HierarchyDataObject2 = _HierarchyApi.GetHierarchyData("Tree", "Root");
                _HierarchyDataObject1.Id.ShouldEqual(_HierarchyDataObject.Id);
                _HierarchyDataObject2.Id.ShouldEqual(_HierarchyDataObject.Id);
            })

            .Then("I can use the Hierarchy Data to bind to Organization object", () =>
            {

                _RelationshipObject1 = new RelationshipObject()
                {
                    ReferenceObjectId = _HierarchyDataObject.Id,
                    RelationshipType = "Tree"
                };

                _RelationShipApi.Save(_OrganizationObject1.OrganizationId, _RelationshipObject1);
                _RelationShipApi.Save(_OrganizationObject2.OrganizationId, _RelationshipObject1);

                _RelationshipObject2 = _RelationShipApi.GetOneToOne(_OrganizationObject1.OrganizationId, _RelationshipObject1.RelationshipType);
                _RelationshipObject3 = _RelationShipApi.GetOneToOne(_OrganizationObject2.OrganizationId, _RelationshipObject1.RelationshipType);

                _RelationshipObject2.ReferenceObjectId.ShouldEqual(_RelationshipObject3.ReferenceObjectId);
                _RelationshipObject2.Ordinal.ShouldEqual(_RelationshipObject3.Ordinal);
            })
            .WithScenario("How to create Hierarchy in Organization")
            .Given("Remove the relationship between Organ1 and Organ2", () =>
            {
                _RelationShipApi.Remove(_OrganizationObject1.OrganizationId);
                _RelationShipApi.Remove(_OrganizationObject2.OrganizationId, "Tree");
            })
            .And("Create a child Hierarchy data ", () =>
            {
                _HierarchyDataObject2 = new HierarchyDataObject()
                {
                    Code = "1111",
                    Description = "Sample",
                    HierarchyType = "Tree",
                    Name = "Leaf",
                    ParentHierarchyDataId = _HierarchyDataObject.Id
                };
                _HierarchyApi.Save(_HierarchyDataObject2);
            })
            .When("I add the hierarchy data to Organization", () =>
            {
                _OrganizationObject1.Hierarchies.Add("Tree", _HierarchyDataObject.Id);

                _OrganizationObject2.Hierarchies.Add("Tree", _HierarchyDataObject2.Id);

                _OrganizationApi.Save(_OrganizationObject1);
                _OrganizationApi.Save(_OrganizationObject2);

            })
            .Then("I can get children HierarchyData by Hierarchy", () =>
                 {
                     _HierarchyDataObject1 = null;
                     _HierarchyDataObject1 = _HierarchyApi.GetImmediateChildren("Tree", _HierarchyDataObject.Id).FirstOrDefault();
                     _HierarchyDataObject1.Id.ShouldEqual(_HierarchyDataObject2.Id);
                 })
            .WithScenario("Delete the children Hierarchy Data")
            .Given("an Existing parent Hierarchy Data and an existing child", () => { })
            .When("I delete the parent hierarchy Data", () =>
                 {
                     _HierarchyApi.DeleteHierarchyData(_HierarchyDataObject.Id);
                 })
             .Then("I cannot get the parent data, and Organization should not have this Hierarchy data", () =>
                  {

                  });

            this.CleanUp();
        }
 /// <summary>
 /// Save a hierarchy data object. 
 /// </summary>
 /// <param name="hierarchyDataObject"></param>
 public string SaveXml(HierarchyDataObject hierarchyDataObject)
 {
     return SaveJson(hierarchyDataObject);
 }
 private static void HierarchizeHierarchyData(IEnumerable<HierarchyDataObject> allHierarchyDataObjects, HierarchyDataObject parentHierarchyData, IList<HierarchyDataObject> results, int hierarchyLevel)
 {
     results.Add(ResolveHierarchyDisplayName(parentHierarchyData, hierarchyLevel));
     IEnumerable<HierarchyDataObject> childHierarchyDataObjects = allHierarchyDataObjects.Where(h => h.ParentHierarchyDataId == parentHierarchyData.HierarchyDataId);
     foreach (HierarchyDataObject childHierarchyDataObject in childHierarchyDataObjects)
         HierarchizeHierarchyData(allHierarchyDataObjects, childHierarchyDataObject, results, hierarchyLevel + 1);
 }
 /// <summary>
 /// Save a hierarchy data object. 
 /// </summary>
 /// <param name="hierarchyDataObject"></param>
 public string SaveJson(HierarchyDataObject hierarchyDataObject)
 {
     if (hierarchyDataObject == null)
         throw new BadRequestException(string.Format(CultureInfo.InvariantCulture, Resources.HierarchyObjectCannotBeNull));
     try
     {
         hierarchyApi.Save(hierarchyDataObject);
         return hierarchyDataObject.HierarchyDataId.ToString();
     }
     catch (ArgumentException ex)
     {
         throw new BadRequestException(string.Format(CultureInfo.InvariantCulture, ex.Message));
     }
     catch (BadRequestException bad)
     {
         throw new BadRequestException(string.Format(CultureInfo.InvariantCulture, bad.Message));
     }
     catch (FormatException formatEx)
     {
         throw new BadRequestException(string.Format(CultureInfo.InvariantCulture, formatEx.Message));
     }
     catch (Exception exp)
     {
         Logger.Instance(this).Error(exp);
         throw new InternalServerErrorException();
     }
 }
        /// <summary>
        /// Find hierarchy data in all types by custom predicates.
        /// </summary>
        /// <param name="predicate">linq predicate which supports properties of <see cref="RapidWebDev.Platform.HierarchyDataObject"/> for query expression.</param>
        /// <param name="orderby">dynamic orderby command</param>
        /// <param name="pageIndex">current paging index</param>
        /// <param name="pageSize">page size</param>
        /// <param name="recordCount">total hit records count</param>
        /// <returns></returns>
        public IEnumerable<HierarchyDataObject> FindHierarchyData(LinqPredicate predicate, string orderby, int pageIndex, int pageSize, out int recordCount)
        {
            try
            {
                using (MembershipDataContext ctx = DataContextFactory.Create<MembershipDataContext>())
                {
                    IQueryable<HierarchyData> q = from hd in ctx.HierarchyDatas
                                                   where hd.ApplicationId == this.authenticationContext.ApplicationId
                                                   select hd;

                    if (predicate != null && !string.IsNullOrEmpty(predicate.Expression))
                        q = q.Where(predicate.Expression, predicate.Parameters);

                    if (!Kit.IsEmpty(orderby))
                        q = q.OrderBy(orderby);

                    recordCount = q.Count();
                    List<HierarchyData> hierarchyDataSets = q.Skip(pageIndex * pageSize).Take(pageSize).ToList();
                    List<HierarchyDataObject> hierarchyDataObjects = new List<HierarchyDataObject>();
                    foreach (HierarchyData entity in hierarchyDataSets)
                    {
                        HierarchyDataObject hierarchyDataObject = new HierarchyDataObject
                        {
                            HierarchyDataId = entity.HierarchyDataId,
                            HierarchyType = entity.HierarchyType,
                            Code = entity.Code,
                            Name = entity.Name,
                            Description = entity.Description,
                            ParentHierarchyDataId = entity.ParentHierarchyDataId,
                            ExtensionDataTypeId = entity.ExtensionDataTypeId,
                            CreatedBy = entity.CreatedBy,
                            CreatedDate = LocalizationUtility.ConvertUtcTimeToClientTime(entity.CreatedDate),
                            LastUpdatedBy = entity.LastUpdatedBy,
                            LastUpdatedDate = LocalizationUtility.ConvertUtcTimeToClientTime(entity.LastUpdatedDate)
                        };

                        hierarchyDataObject.ParseExtensionPropertiesFrom(entity);
                        hierarchyDataObjects.Add(hierarchyDataObject);
                    }

                    return hierarchyDataObjects;
                }
            }
            catch (Exception exp)
            {
                Logger.Instance(this).Error(exp);
                throw;
            }
        }
        private IEnumerable<HierarchyDataObject> GetAllHierarchyDataInternal(string hierarchyType)
        {
            Kit.NotNull(hierarchyType, "hierarchyType");

            CloneableList<HierarchyDataObject> results = base.GetCacheObject<CloneableList<HierarchyDataObject>>(hierarchyType);
            if (results == null)
            {
                using (MembershipDataContext ctx = DataContextFactory.Create<MembershipDataContext>())
                {
                    List<HierarchyData> entities = (from hd in ctx.HierarchyDatas
                                                    where hd.ApplicationId == this.authenticationContext.ApplicationId && hd.HierarchyType == hierarchyType
                                                    select hd).ToList();

                    results = new CloneableList<HierarchyDataObject>();
                    foreach (HierarchyData entity in entities)
                    {
                        HierarchyDataObject hierarchyDataObject = new HierarchyDataObject
                        {
                            HierarchyDataId = entity.HierarchyDataId,
                            HierarchyType = entity.HierarchyType,
                            Code = entity.Code,
                            Name = entity.Name,
                            Description = entity.Description,
                            ParentHierarchyDataId = entity.ParentHierarchyDataId,
                            CreatedBy = entity.CreatedBy,
                            CreatedDate = entity.CreatedDate,
                            ExtensionDataTypeId = entity.ExtensionDataTypeId,
                            LastUpdatedBy = entity.LastUpdatedBy,
                            LastUpdatedDate = entity.LastUpdatedDate
                        };

                        hierarchyDataObject.ParseExtensionPropertiesFrom(entity);
                        results.Add(hierarchyDataObject);
                    }

                    // only cache the business objects with UTC datetime
                    base.AddCache(hierarchyType, results);
                }
            }

            // get the deep copy of the list so that the timezone change doesn't impact the cached copy.
            results = results.Clone();

            // convert UTC datetime into client timezone.
            results.ForEach(h =>
                {
                    h.CreatedDate = LocalizationUtility.ConvertUtcTimeToClientTime(h.CreatedDate);
                    h.LastUpdatedDate = LocalizationUtility.ConvertUtcTimeToClientTime(h.LastUpdatedDate);
                });

            return results;
        }
        /// <summary>
        /// Save a hierarchy data object.
        /// </summary>
        /// <param name="hierarchyDataObject"></param>
        public void Save(HierarchyDataObject hierarchyDataObject)
        {
            Kit.NotNull(hierarchyDataObject, "hierarchyDataObject");
            Kit.NotNull(hierarchyDataObject.Name, "hierarchyDataObject.Name");
            Kit.NotNull(hierarchyDataObject.HierarchyType, "hierarchyDataObject.HierarchyType");

            using (MembershipDataContext ctx = DataContextFactory.Create<MembershipDataContext>())
            {
                using (ValidationScope validationScope = new ValidationScope(true))
                {
                    // check whether the hierarchy type of parent equals to current one's
                    if (hierarchyDataObject.ParentHierarchyDataId.HasValue)
                    {
                        HierarchyDataObject parentHierarchyDataObject = this.GetHierarchyData(hierarchyDataObject.ParentHierarchyDataId.Value);
                        if (parentHierarchyDataObject == null)
                            validationScope.Error(Resources.InvalidParentHierarchyDataId);
                    }

                    // whether to check cycle reference on parent hierarchy data id?
                    // TODO:

                    // check duplicate hierarchy data name in a hierarchy type.
                    HierarchyDataObject duplicateHierarchyDataObject = this.GetHierarchyData(hierarchyDataObject.HierarchyType, hierarchyDataObject.Name);
                    if (duplicateHierarchyDataObject != null && duplicateHierarchyDataObject.HierarchyDataId != hierarchyDataObject.HierarchyDataId)
                        validationScope.Error(Resources.DuplicateHierarchyDataName);

                    // check whether the hierarchy type has been changed.
                    if (hierarchyDataObject.HierarchyDataId != Guid.Empty)
                    {
                        var existedHierarchyDataObject = this.GetHierarchyData(hierarchyDataObject.HierarchyDataId);
                        if (existedHierarchyDataObject == null)
                            validationScope.Error(Resources.InvalidHierarchyDataId);

                        if (existedHierarchyDataObject.HierarchyType != hierarchyDataObject.HierarchyType)
                            validationScope.Error(Resources.HierarchyTypeCannotBeChanged);
                    }
                }

                HierarchyData hierarchyData = null;
                if (hierarchyDataObject.HierarchyDataId == Guid.Empty)
                {
                    hierarchyData = ExtensionObjectFactory.Create<HierarchyData>(hierarchyDataObject);
                    hierarchyData.ApplicationId = this.authenticationContext.ApplicationId;
                    hierarchyData.CreatedBy = this.authenticationContext.User.UserId;
                    hierarchyData.CreatedDate = DateTime.UtcNow;

                    ctx.HierarchyDatas.InsertOnSubmit(hierarchyData);
                }
                else
                {
                    hierarchyData = ctx.HierarchyDatas.FirstOrDefault(d => d.HierarchyDataId == hierarchyDataObject.HierarchyDataId);
                }

                hierarchyData.HierarchyType = hierarchyDataObject.HierarchyType;
                hierarchyData.ParentHierarchyDataId = hierarchyDataObject.ParentHierarchyDataId;
                hierarchyData.Code = hierarchyDataObject.Code;
                hierarchyData.Name = hierarchyDataObject.Name;
                hierarchyData.Description = hierarchyDataObject.Description;
                hierarchyData.LastUpdatedBy = this.authenticationContext.User.UserId;
                hierarchyData.LastUpdatedDate = DateTime.UtcNow;

                hierarchyData.ParseExtensionPropertiesFrom(hierarchyDataObject);
                ctx.SubmitChanges();

                hierarchyDataObject.HierarchyDataId = hierarchyData.HierarchyDataId;
                hierarchyDataObject.CreatedBy = hierarchyData.CreatedBy;
                hierarchyDataObject.CreatedDate = LocalizationUtility.ConvertUtcTimeToClientTime(hierarchyData.CreatedDate);
                hierarchyDataObject.LastUpdatedBy = hierarchyData.LastUpdatedBy;
                hierarchyDataObject.LastUpdatedDate = LocalizationUtility.ConvertUtcTimeToClientTime(hierarchyData.LastUpdatedDate);

                base.RemoveCache(hierarchyDataObject.HierarchyDataId);
                base.RemoveCache(hierarchyData.HierarchyType);
            }
        }
        /// <summary>
        /// Get a hierarchy data object by id.
        /// </summary>
        /// <param name="hierarchyDataId"></param>
        /// <returns></returns>
        public HierarchyDataObject GetHierarchyData(Guid hierarchyDataId)
        {
            HierarchyDataObject hierarchyDataObject = base.GetCacheObject<HierarchyDataObject>(hierarchyDataId);

            // if the object is not cached, then load it from database.
            if (hierarchyDataObject == null)
            {
                using (MembershipDataContext ctx = DataContextFactory.Create<MembershipDataContext>())
                {
                    HierarchyData entity = (from hd in ctx.HierarchyDatas
                                            where hd.ApplicationId == this.authenticationContext.ApplicationId && hd.HierarchyDataId == hierarchyDataId
                                            select hd).FirstOrDefault();

                    // nothing found.
                    if (entity == null) return null;

                    hierarchyDataObject = new HierarchyDataObject
                    {
                        HierarchyDataId = entity.HierarchyDataId,
                        HierarchyType = entity.HierarchyType,
                        Code = entity.Code,
                        Name = entity.Name,
                        Description = entity.Description,
                        ParentHierarchyDataId = entity.ParentHierarchyDataId,
                        CreatedBy = entity.CreatedBy,
                        CreatedDate = entity.CreatedDate,
                        ExtensionDataTypeId = entity.ExtensionDataTypeId,
                        LastUpdatedBy = entity.LastUpdatedBy,
                        LastUpdatedDate = entity.LastUpdatedDate
                    };

                    // parse dynamic properties.
                    hierarchyDataObject.ParseExtensionPropertiesFrom(entity);

                    // cache the business copy with UTC datetime.
                    base.AddCache(hierarchyDataObject.HierarchyDataId, hierarchyDataObject);
                }
            }

            // only return the copy so that the datetime convertion doesn't impact the cached object.
            hierarchyDataObject = hierarchyDataObject.Clone();

            // convert UTC datetime into client timezone before return.
            hierarchyDataObject.CreatedDate = LocalizationUtility.ConvertUtcTimeToClientTime(hierarchyDataObject.CreatedDate);
            hierarchyDataObject.LastUpdatedDate = LocalizationUtility.ConvertUtcTimeToClientTime(hierarchyDataObject.LastUpdatedDate);
            return hierarchyDataObject;
        }