private static List<FirmInstitutionOptionValue> GetOptionValueList(Guid idFirmInstitution, FirmInstitutionOptionValue optionValueRoot)
        {
            using (UpsilabEntities context = new UpsilabEntities())
            {
                var query = from optionValue in context.FirmInstitutionOptionValue.Include("FirmInstitutionOptionAttributeValue")
                            join option in context.Option on optionValue.idOption equals option.idOption
                            where optionValue.idFirmInstitution.Equals(idFirmInstitution)
                            where option.idParent.Value.Equals(optionValueRoot.idOption)
                            select optionValue;

                List<Data.Model.FirmInstitutionOptionValue> returnValue = new List<FirmInstitutionOptionValue>();
                foreach (var optionValue in query.ToList())
                {
                    context.LoadProperty(optionValue, "FirmInstitutionOptionAttributeValue");
                    returnValue.Add(optionValue);
                    returnValue.AddRange(GetOptionValueList(idFirmInstitution, optionValue));
                }

                return returnValue;
            }
        }
        public List<FirmInstitutionOptionValue> GetSelectedOptionValues(FIDetailModel model)
        {
            List<FirmInstitutionOptionValue> retVal = new List<FirmInstitutionOptionValue>();

            var optionParents = model.Option.Where(o => o.idParent.HasValue.Equals(false));
            foreach (var optParent in optionParents)
            {
                var dataExtract = GetSelectedOptionValuesByParent(model, optParent.idOption);
                bool hasNoChildOption = model.Option.Count(o => o.idParent.HasValue && o.idParent.Value.Equals(optParent.idOption)) == 0;
                if (dataExtract.Count > 0 || hasNoChildOption)
                {
                    FirmInstitutionOptionValue newVal = new FirmInstitutionOptionValue();
                    newVal.idFirmInstitution = model.FirmInstitution.idFirmInstitution;
                    newVal.Option = optParent;
                    newVal.idOption = optParent.idOption;
                    retVal.Add(newVal);
                    if (!hasNoChildOption)
                    {
                        retVal.AddRange(dataExtract);
                    }
                }
            }

            return retVal;
        }
        public List<FirmInstitutionOptionValue> GetSelectedOptionValuesByParent(FIDetailModel model, int idParent)
        {
            List<FirmInstitutionOptionValue> retVal = new List<FirmInstitutionOptionValue>();
            var optParent = model.Option.Where(o => o.idOption.Equals(idParent)).FirstOrDefault();
            if (optParent != null)
            {
                var optChildren = model.Option.Where(o => o.idParent.HasValue && o.idParent.Value.Equals(idParent));
                foreach (var optChild in optChildren)
                {
                    bool isSelected = !optParent.SingleOption.HasValue;
                    string idPrefix = string.Empty;
                    if (optParent.SingleOption.HasValue)
                    {
                        if (optParent.SingleOption.Value) idPrefix = "rb_{0}_{1}";
                        else idPrefix = "chk_{0}_{1}";
                        string postDataName = string.Format(idPrefix, optChild.idParent.Value, optChild.idOption);
                        if (!string.IsNullOrEmpty(Request.Params[postDataName]) && Request.Params[postDataName].ToLower().Equals("c"))
                        {
                            isSelected = true;
                        }
                    }

                    if (isSelected)
                    {
                        FirmInstitutionOptionValue newVal = new FirmInstitutionOptionValue();
                        newVal.idFirmInstitution = model.FirmInstitution.idFirmInstitution;
                        newVal.Option = optChild;
                        newVal.idOption = optChild.idOption;
                        retVal.Add(newVal);
                        if (optChild.SingleOption.HasValue)
                        {
                            retVal.AddRange(GetSelectedOptionValuesByParent(model, optChild.idOption));
                        }
                    }

                    if (model.Option.Where(o => o.idParent.HasValue && o.idParent.Value.Equals(optChild.idOption)).Count() > 0)
                    {
                        retVal.AddRange(GetSelectedOptionValuesByParent(model, optChild.idOption));
                    }
                }
            }

            return retVal;
        }
        public static bool UpdateInstitutionOptions(Guid idFirmInstitution, List<FirmInstitutionOptionValue> SelectedOptions)
        {
            bool retVal = true;
            try
            {
                var parentOptions = SelectedOptions.Where(so => so.Option.idParent.HasValue.Equals(false));
                foreach (var parentOption in parentOptions)
                {

                    List<Data.Model.Option> optList = OptionBL.GetOptionsByIdParent(parentOption.idOption);

                    #region Delete existing OptionAttributeValue under Parent
                    List<FirmInstitutionOptionAttributeValue> toBeDeletedAttr = new List<FirmInstitutionOptionAttributeValue>();
                    using (UpsilabEntities db = new UpsilabEntities())
                    {
                        foreach (var opt in optList)
                        {
                            var deleteAttr = (from toBeDel in db.FirmInstitutionOptionAttributeValue.ToList()
                                              join o in opt.OptionAttribute on toBeDel.idOptionAttrbiute equals o.idOptionAttribute
                                              where toBeDel.idFirmInstitution.Equals(idFirmInstitution)
                                              select toBeDel).ToList();
                            toBeDeletedAttr.AddRange(deleteAttr);
                        }

                        foreach (var toBeDel in toBeDeletedAttr)
                        {
                            db.FirmInstitutionOptionAttributeValue.DeleteObject(toBeDel);
                        }

                        db.SaveChanges();
                    }
                    #endregion

                    #region delete OptionValue
                    //Delete existing OptionValue under Parent
                    List<FirmInstitutionOptionValue> optToBeDeletedOpt = new List<FirmInstitutionOptionValue>();
                    using (UpsilabEntities db = new UpsilabEntities())
                    {
                        optToBeDeletedOpt = (from toBeDel in db.FirmInstitutionOptionValue.Include("FirmInstitutionOptionAttributeValue").ToList()
                                          join opt in optList on toBeDel.idOption equals opt.idOption
                                          where toBeDel.idFirmInstitution.Equals(idFirmInstitution)
                                          select toBeDel).ToList();

                        foreach (var optionValueToDel in optToBeDeletedOpt)
                        {
                            //2- Delete option attribute values attached to option value
                            IList<FirmInstitutionOptionAttributeValue> lstOptionAttributeValues = new List<FirmInstitutionOptionAttributeValue>(optionValueToDel.FirmInstitutionOptionAttributeValue);
                            foreach (var item in lstOptionAttributeValues)
                            {
                                var optionAttrValueToBeDel = optionValueToDel.FirmInstitutionOptionAttributeValue.Where(oa => oa.idOptionAttributeValue == item.idOptionAttributeValue).FirstOrDefault();
                                if (optionAttrValueToBeDel != null)
                                {
                                    db.FirmInstitutionOptionAttributeValue.DeleteObject(optionAttrValueToBeDel);
                                }
                            }

                            //3- Delete option values
                            db.FirmInstitutionOptionValue.DeleteObject(optionValueToDel);
                        }

                        db.SaveChanges();
                    }
                }

                //Insert new OptionValue
                using (UpsilabEntities insertContext = new UpsilabEntities())
                {
                    foreach (var toBeAdded in SelectedOptions)
                    {
                        FirmInstitutionOptionValue newOptVal = new FirmInstitutionOptionValue()
                        {
                            idFirmInstitution = idFirmInstitution,
                            idOption = toBeAdded.idOption,
                            Value = string.Empty
                        };


                        insertContext.FirmInstitutionOptionValue.AddObject(newOptVal);
                        insertContext.SaveChanges();

                        if (toBeAdded.FirmInstitutionOptionAttributeValue.Count > 0)
                        {
                            foreach (var optAttr in toBeAdded.FirmInstitutionOptionAttributeValue)
                            {
                                FirmInstitutionOptionAttributeValue newOptAttrVal = new FirmInstitutionOptionAttributeValue()
                                {
                                    idFirmInstitution = idFirmInstitution,
                                    idOptionAttrbiute = optAttr.idOptionAttrbiute,
                                    idFirmInstitutionOptionValue = newOptVal.idFirmInstitutionOptionValue,
                                    Value = optAttr.Value,
                                };

                                insertContext.FirmInstitutionOptionAttributeValue.AddObject(newOptAttrVal);
                                insertContext.SaveChanges();
                            }
                        }
                    }

                }
                    #endregion
            }
            catch (Exception e)
            {
                retVal = false;
                Log.Log.AppendException(e);
            }
            return retVal;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="idFirmInstitution"></param>
        /// <param name="option"></param>
        /// <param name="idOptionAttrbiute"></param>
        /// <param name="value"></param>
        /// <param name="fieldType"></param>
        public static void SaveFirmInstitutionOptionValue(Guid idFirmInstitution, Upsilab.Data.Model.Option option, int idOptionAttrbiute, string value, string fieldType)
        {
            int idOption = option.idOption;

            //Insert new OptionValue
            using (UpsilabEntities db = new UpsilabEntities())
            {
                //Get current firmInstitution
                Data.Model.FirmInstitution firmInstitution = (from firm in db.FirmInstitution
                                                              where firm.idFirmInstitution == idFirmInstitution
                                                              select firm).FirstOrDefault();

                #region TEXTBOX, DROPDOWN : txt, dt, enum
                //1- Save option attribute value (simple textbox / textarea)
                if (fieldType == "txtAttr" || fieldType == "dtAttr" || fieldType == "cbx")
                {
                    FirmInstitutionOptionAttributeValue optionAttributeValue = (from firmoav in db.FirmInstitutionOptionAttributeValue.Include("FirmInstitutionOptionValue")
                                                                                where firmoav.idFirmInstitution == idFirmInstitution && firmoav.idOptionAttrbiute == idOptionAttrbiute
                                                                                select firmoav).FirstOrDefault();

                    if (optionAttributeValue != null)
                    {
                        if (optionAttributeValue.Value != value) //update if not equal
                        {
                            optionAttributeValue.Value = value;
                            optionAttributeValue.DateUpdated = DateTime.Now;
                        }
                        else
                        {
                            //Do nothing if equal
                        }
                    }
                    else if (!string.IsNullOrEmpty(value)) //Insert if value is not empty
                    {
                        //Check if FirmInstitutionOptionValue exists
                        FirmInstitutionOptionValue optionValue = (from lov in db.FirmInstitutionOptionValue
                                                                   where lov.idFirmInstitution == idFirmInstitution && lov.idOption == idOption
                                                                   select lov).FirstOrDefault();

                        if (optionValue == null) //insert option value
                        {
                            optionValue = new FirmInstitutionOptionValue()
                            {
                                idFirmInstitution = idFirmInstitution,
                                idOption = idOption,
                                Value = string.Empty,
                                DateCreated = DateTime.Now,
                                DateUpdated = DateTime.Now
                            };

                            //Add FirmInstitutionOptionValue to DB : don't save yet
                            db.FirmInstitutionOptionValue.AddObject(optionValue);

                            //Insert parent ??
                            while (option.idParent.HasValue)
                            {
                                FirmInstitutionOptionValue optionParentValue = (from lov in db.FirmInstitutionOptionValue.Include("Option")
                                                                                 where lov.idFirmInstitution == idFirmInstitution && lov.idOption == option.idParent
                                                                                 select lov).FirstOrDefault();

                                if (optionParentValue == null)
                                {
                                    optionParentValue = new FirmInstitutionOptionValue()
                                    {
                                        idFirmInstitution = idFirmInstitution,
                                        idOption = option.idParent.Value,
                                        Value = string.Empty,
                                        DateCreated = DateTime.Now,
                                        DateUpdated = DateTime.Now
                                    };

                                    //Add FirmInstitutionOptionValue to DB : don't save yet
                                    db.FirmInstitutionOptionValue.AddObject(optionParentValue);

                                    //Check if this parent option has already parent ?
                                    option = optionParentValue.Option;
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }

                        //Insert optionattrubutevalue
                        FirmInstitutionOptionAttributeValue newFirmInstitutionOptionAttributeValue = new FirmInstitutionOptionAttributeValue()
                        {
                            idFirmInstitution = idFirmInstitution,
                            idOptionAttrbiute = idOptionAttrbiute,
                            idFirmInstitutionOptionValue = optionValue.idFirmInstitutionOptionValue,
                            Value = value,
                            DateCreated = DateTime.Now,
                            DateUpdated = DateTime.Now
                        };

                        //Add FirmInstitutionOptionAttributeValue to DB : don't save yet
                        optionValue.FirmInstitutionOptionAttributeValue.Add(newFirmInstitutionOptionAttributeValue);
                    }
                }
                #endregion

                #region RADIO BUTTON : rb
                //2- Save option attribute value (Radio button)
                else if (fieldType == "rb")
                {
                    //Delete old rb
                    IList<FirmInstitutionOptionValue> optionValues = (from lov in db.FirmInstitutionOptionValue.Include("FirmInstitutionOptionAttributeValue")
                                                                       where lov.idFirmInstitution == idFirmInstitution && lov.Option.idParent == option.idParent
                                                                       select lov).ToList();

                    //Delete option attribute values attached to option value
                    if (optionValues != null)
                    {
                        foreach (var optionValue in optionValues)
                        {
                            IList<FirmInstitutionOptionAttributeValue> lstOptionAttributeValues = new List<FirmInstitutionOptionAttributeValue>(optionValue.FirmInstitutionOptionAttributeValue);
                            foreach (var item in lstOptionAttributeValues)
                            {
                                var optionAttrValueToBeDel = optionValue.FirmInstitutionOptionAttributeValue.Where(oa => oa.idOptionAttributeValue == item.idOptionAttributeValue).FirstOrDefault();
                                db.FirmInstitutionOptionAttributeValue.DeleteObject(optionAttrValueToBeDel);
                            }

                            db.FirmInstitutionOptionValue.DeleteObject(optionValue);

                            //Delete child option value
                            IList<FirmInstitutionOptionValue> lstOptionValuesChild = (from lov in db.FirmInstitutionOptionValue.Include("FirmInstitutionOptionAttributeValue")
                                                                                       where lov.idFirmInstitution == idFirmInstitution && lov.Option.idParent == optionValue.idOption
                                                                                       select lov).ToList();

                            if (lstOptionValuesChild != null)
                            {
                                foreach (var optionValueChild in lstOptionValuesChild)
                                {
                                    lstOptionAttributeValues = new List<FirmInstitutionOptionAttributeValue>(optionValueChild.FirmInstitutionOptionAttributeValue);
                                    foreach (var item in lstOptionAttributeValues)
                                    {
                                        var optionAttrValueToBeDel = optionValueChild.FirmInstitutionOptionAttributeValue.Where(oa => oa.idOptionAttributeValue == item.idOptionAttributeValue).FirstOrDefault();
                                        db.FirmInstitutionOptionAttributeValue.DeleteObject(optionAttrValueToBeDel);
                                    }

                                    db.FirmInstitutionOptionValue.DeleteObject(optionValueChild);
                                }
                            }
                        }

                    }

                    //Insert new rb
                    FirmInstitutionOptionValue newOptionValue = new FirmInstitutionOptionValue()
                    {
                        idFirmInstitution = idFirmInstitution,
                        idOption = idOption,
                        Value = string.Empty,
                        DateCreated = DateTime.Now,
                        DateUpdated = DateTime.Now
                    };

                    //Add FirmInstitutionOptionValue to DB : don't save yet
                    db.FirmInstitutionOptionValue.AddObject(newOptionValue);

                    //Insert parent ??
                    while (option.idParent.HasValue)
                    {
                        FirmInstitutionOptionValue optionParentValue = (from lov in db.FirmInstitutionOptionValue.Include("Option")
                                                                 where lov.idFirmInstitution == idFirmInstitution && lov.idOption == option.idParent
                                                                 select lov).FirstOrDefault();

                        if (optionParentValue == null)
                        {
                            optionParentValue = new FirmInstitutionOptionValue()
                            {
                                idFirmInstitution = idFirmInstitution,
                                idOption = option.idParent.Value,
                                Value = string.Empty,
                                DateCreated = DateTime.Now,
                                DateUpdated = DateTime.Now
                            };

                            //Add FirmInstitutionOptionValue to DB : don't save yet
                            db.FirmInstitutionOptionValue.AddObject(optionParentValue);

                            //Check if this parent option has already parent ?
                            option = optionParentValue.Option;
                        }
                        else
                        {
                            break;
                        }
                    }
                }
                #endregion

                #region CHECKBOX : chk
                //3- Save option attribute value (Checkbox)
                else if (fieldType == "chk")
                {
                    FirmInstitutionOptionValue optionValue;

                    if (value == "false")
                    {
                        //Delete old chk
                        optionValue = (from lov in db.FirmInstitutionOptionValue.Include("FirmInstitutionOptionAttributeValue")
                                       where lov.idFirmInstitution == idFirmInstitution && lov.idOption == idOption
                                       select lov).FirstOrDefault();

                        //Delete option attribute values attached to option value
                        if (optionValue != null)
                        {
                            IList<FirmInstitutionOptionAttributeValue> lstOptionAttributeValues = new List<FirmInstitutionOptionAttributeValue>(optionValue.FirmInstitutionOptionAttributeValue);
                            foreach (var item in lstOptionAttributeValues)
                            {
                                var optionAttrValueToBeDel = optionValue.FirmInstitutionOptionAttributeValue.Where(oa => oa.idOptionAttributeValue == item.idOptionAttributeValue).FirstOrDefault();
                                db.FirmInstitutionOptionAttributeValue.DeleteObject(optionAttrValueToBeDel);
                            }

                            db.FirmInstitutionOptionValue.DeleteObject(optionValue);

                            //Delete child option value
                            IList<FirmInstitutionOptionValue> lstOptionValuesChild = (from lov in db.FirmInstitutionOptionValue.Include("FirmInstitutionOptionAttributeValue")
                                                                               where lov.idFirmInstitution == idFirmInstitution && lov.Option.idParent == optionValue.idOption
                                                                               select lov).ToList();

                            if (lstOptionValuesChild != null)
                            {
                                foreach (var optionValueChild in lstOptionValuesChild)
                                {
                                    lstOptionAttributeValues = new List<FirmInstitutionOptionAttributeValue>(optionValueChild.FirmInstitutionOptionAttributeValue);
                                    foreach (var item in lstOptionAttributeValues)
                                    {
                                        var optionAttrValueToBeDel = optionValueChild.FirmInstitutionOptionAttributeValue.Where(oa => oa.idOptionAttributeValue == item.idOptionAttributeValue).FirstOrDefault();
                                        db.FirmInstitutionOptionAttributeValue.DeleteObject(optionAttrValueToBeDel);
                                    }

                                    db.FirmInstitutionOptionValue.DeleteObject(optionValueChild);
                                }
                            }
                        }
                    }
                    else if (value == "true")
                    {
                        //Insert new chk
                        optionValue = new FirmInstitutionOptionValue()
                        {
                            idFirmInstitution = idFirmInstitution,
                            idOption = idOption,
                            Value = string.Empty,
                            DateCreated = DateTime.Now,
                            DateUpdated = DateTime.Now
                        };

                        //Add FirmInstitutionOptionValue to DB : don't save yet
                        db.FirmInstitutionOptionValue.AddObject(optionValue);

                        //Insert parent ??
                        while (option.idParent.HasValue)
                        {
                            FirmInstitutionOptionValue optionParentValue = (from lov in db.FirmInstitutionOptionValue.Include("Option")
                                                                     where lov.idFirmInstitution == idFirmInstitution && lov.idOption == option.idParent
                                                                     select lov).FirstOrDefault();

                            if (optionParentValue == null)
                            {
                                optionParentValue = new FirmInstitutionOptionValue()
                                {
                                    idFirmInstitution = idFirmInstitution,
                                    idOption = option.idParent.Value,
                                    Value = string.Empty,
                                    DateCreated = DateTime.Now,
                                    DateUpdated = DateTime.Now
                                };

                                //Add FirmInstitutionOptionValue to DB : don't save yet
                                db.FirmInstitutionOptionValue.AddObject(optionParentValue);

                                //Check if this parent option has already parent ?
                                option = optionParentValue.Option;
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                }
                #endregion

                //6- Commit all changes here
                db.SaveChanges();
            }
        }