void btnDeleteNode_Click(object sender, EventArgs e)
        {
            errorText.InnerText = "";
            errorText.Visible   = false;

            if (OrgUnitTree.SelectedNode != null && int.Parse(OrgUnitTree.SelectedNode.Attributes["OrgUnitId"]) > 0)
            {
                int        orgUnitID = int.Parse(OrgUnitTree.SelectedNode.Attributes["OrgUnitId"]);
                EF.OrgUnit orgUnit   = EF.DataContext.Current.OrgUnits.Include("OrgUnitResources").First(ou => ou.OrgUnitId == orgUnitID);

                var resourcesToUpdate = EF.DataContext.Current.OrgUnitResources.Include("Resource").Include("OrgUnitresources.resource.ResourceType");
                var driversToUpdate   = resourcesToUpdate.Where(x => x.OrgUnitId == orgUnitID && x.Resource.ResourceType.ResourceTypeId == (int)eResourceType.Driver).Select(d => d.ResourceId).ToList();
                var vehiclesToUpdate  = resourcesToUpdate.Where(x => x.OrgUnitId == orgUnitID && x.Resource.ResourceType.ResourceTypeId == (int)eResourceType.Vehicle).Select(v => v.ResourceId).ToList();

                if (orgUnit != null)
                {
                    EF.DataContext.Current.DeleteObject(orgUnit);
                    EF.DataContext.Current.SaveChanges();
                }

                UpdateThirdPartyTelematicsDrivers(driversToUpdate);
                UpdateThirdPartyTelematicsVehicles(vehiclesToUpdate);
            }
            LoadOrgUnitTree();
            LoadResourceList();
        }
        /// <summary>
        /// Finds the resource units which have been newly added into an org unit and
        /// creates links in the OrgUnitResource table to that effect
        /// Returns the IDs of resources added
        /// </summary>
        /// <param name="orgUnit"></param>
        private IEnumerable <int> AddResourcesToOrgUnit(EF.OrgUnit orgUnit)
        {
            List <int> addedResourceIDs = new List <int>();

            foreach (RadListBoxItem item in lbResourcesInGroup.Items)
            {
                int         resourceId = int.Parse(item.Value);
                EF.Resource resource   = _resources.FirstOrDefault(r => r.ResourceId == resourceId);
                //If the resource was found and its OrgUnit has changed, update it
                if (resource != null && resource.OrgUnitResources == null || !resource.OrgUnitResources.Any(or => or.OrgUnitId == orgUnit.OrgUnitId))
                {
                    EF.OrgUnitResource our = new EF.OrgUnitResource();
                    our.OrgUnit          = orgUnit;
                    our.Resource         = resource;
                    our.CreateUserId     = this.Page.User.Identity.Name;
                    our.CreateDateTime   = DateTime.Now;
                    our.LastUpdateDate   = DateTime.Now;
                    our.LastUpdateUserId = this.Page.User.Identity.Name;
                    addedResourceIDs.Add(resourceId);

                    EF.DataContext.Current.SaveChanges();
                }
            }

            return(addedResourceIDs);
        }
        void btnAddNode_Click(object sender, EventArgs e)
        {
            if (txtNodeName.Text.Length == 0)
            {
                return;
            }

            // If the user has not specified a Node, select the top level node by default.
            if (OrgUnitTree.SelectedNode == null)
            {
                OrgUnitTree.Nodes[0].Selected = true;
            }

            EF.OrgUnit newUnit = new EF.OrgUnit();
            newUnit.Name             = txtNodeName.Text;
            newUnit.ParentOrgUnitId  = int.Parse(OrgUnitTree.SelectedNode.Attributes["OrgUnitId"]);
            newUnit.CreateDate       = DateTime.Now;
            newUnit.CreateUserId     = Page.User.Identity.Name;
            newUnit.LastUpdateDate   = DateTime.Now;
            newUnit.LastUpdateUserId = Page.User.Identity.Name;
            EF.DataContext.Current.AddToOrgUnits(newUnit);
            EF.DataContext.Current.SaveChanges();

            txtNodeName.Text = string.Empty;
            LoadOrgUnitTree();
            LoadResourceList();
        }
        /// <summary>
        /// Finds the resource units which have been newly removed from an org unit
        /// and removes links in the OrgUnitResource table to that effect.
        /// Returns the IDs of resources removed
        /// </summary>
        /// <param name="orgUnit"></param>
        private IEnumerable <int> RemoveResourcesFromOrgUnit(EF.OrgUnit orgUnit)
        {
            var selectedResourceTypeid = VehiclesRadioButton.Checked ? 1 : 3;
            var selectedResourceType   = new EF.ResourceType()
            {
                ResourceTypeId = selectedResourceTypeid
            };

            var resourcesInDB = orgUnit.OrgUnitResources.Where(ou => ou.Resource.ResourceType.ResourceTypeId == selectedResourceTypeid && ou.OrgUnitId == orgUnit.OrgUnitId).ToList();

            var idsOfResourcesNotInThisGroup = lbResourcesNotInGroup.Items.Select(x => int.Parse(x.Value));
            var resourcesToRemove            = resourcesInDB.Where(x => idsOfResourcesNotInThisGroup.Contains(x.ResourceId));

            foreach (var item in resourcesToRemove)
            {
                orgUnit.OrgUnitResources.Remove(item);
            }
            EF.DataContext.Current.SaveChanges();

            return(resourcesToRemove.Select(x => x.ResourceId));
        }
        protected void OrgUnitTree_NodeEdit(object sender, RadTreeNodeEditEventArgs e)
        {
            errorText.InnerText = "";
            errorText.Visible   = false;

            //It seems that it is not enough for the edit to just happen client side.
            //If this is not done then the changed text reverts after a postback
            RadTreeNode nodeEdited = e.Node;

            nodeEdited.Text = e.Text;

            int orgUnitID = int.Parse(nodeEdited.Attributes["OrgUnitId"]);

            EF.OrgUnit orgUnit = EF.DataContext.Current.OrgUnits.Include("OrgUnitResources").First(ou => ou.OrgUnitId == orgUnitID);

            var resourcesToUpdate = EF.DataContext.Current.OrgUnitResources.Include("Resource").Include("OrgUnitresources.resource.ResourceType");
            var driversToUpdate   = resourcesToUpdate.Where(x => x.OrgUnitId == orgUnitID && x.Resource.ResourceType.ResourceTypeId == (int)eResourceType.Driver).Select(d => d.ResourceId).ToList();
            var vehiclesToUpdate  = resourcesToUpdate.Where(x => x.OrgUnitId == orgUnitID && x.Resource.ResourceType.ResourceTypeId == (int)eResourceType.Vehicle).Select(v => v.ResourceId).ToList();

            UpdateThirdPartyTelematicsDrivers(driversToUpdate);
            UpdateThirdPartyTelematicsVehicles(vehiclesToUpdate);
        }
        private void UpdateOrgUnits(int?ParentOrgUnitId, RadTreeNodeCollection Nodes, bool delete)
        {
            //Ideally OrgUnit would have an Entity Reference to itself which would mean a sub tree could be deleted
            //by simply deleting it's the root node and we would not need to SaveChanges for every new node just to get
            //the OrgUnitId to pass down the tree. However, this jhas not been done as the RadTree requires a ParentId and Id
            //to do its binding. EF4 will fix this by allowing us to have both an FK Id AND an Entity Reference
            foreach (RadTreeNode node in Nodes)
            {
                TreeDataNodeType dataNodeType = (TreeDataNodeType)Enum.Parse(typeof(TreeDataNodeType), node.Attributes["DataNodeType"], true);

                //If Node is an OrgUnit
                if (dataNodeType == TreeDataNodeType.OrgUnit)
                {
                    int        orgUnitId = 0;
                    EF.OrgUnit orgUnit   = null;

                    //New nodes do not have a OrgUnitId
                    if (!string.IsNullOrEmpty(node.Attributes["OrgUnitId"]))
                    {
                        orgUnitId = int.Parse(node.Attributes["OrgUnitId"]);
                        orgUnit   = _orgUnits.FirstOrDefault(ou => ou.OrgUnitId == orgUnitId);
                    }

                    //If the node has been deleted or one of its ancestors, delete it if it is NOT new
                    //then delete its children
                    if (node.Visible == false || delete)
                    {
                        if (orgUnit != null)
                        {
                            foreach (EF.OrgUnitResource our in orgUnit.OrgUnitResources)
                            {
                                EF.DataContext.Current.DeleteObject(our);
                            }

                            EF.DataContext.Current.DeleteObject(orgUnit);
                            EF.DataContext.Current.SaveChanges();
                        }
                    }
                    //If not deleting, then add or update
                    else
                    {
                        //Create the OrgUnit if it's new
                        if (orgUnit == null)
                        {
                            orgUnit = new EF.OrgUnit();
                            EF.DataContext.Current.AddToOrgUnits(orgUnit);
                            _orgUnits.Add(orgUnit);
                        }

                        //Update changed properties
                        if (orgUnit.ParentOrgUnitId != ParentOrgUnitId)
                        {
                            orgUnit.ParentOrgUnitId = ParentOrgUnitId;
                        }

                        if (orgUnit.Name != node.Text)
                        {
                            orgUnit.Name = node.Text;
                        }

                        EF.DataContext.Current.SaveChanges();

                        UpdateOrgUnits(orgUnit.OrgUnitId, node.Nodes, false);
                    }
                }
                else
                {
                }
            }
        }