/// <summary>
        /// From the info provided, return the companyLocationGroup information along with the authorization on that element.
        /// For now we will assume: 1. Company Owner can do everything. 2. The employee can read, but not edit. 3. Everyone else is forbidden.
        /// </summary>
        /// <param name="professionalUserId"></param>
        /// <param name="companyLocationGroupId"></param>
        /// <param name="authState"></param>
        /// <param name="isCompanyOwner"></param>
        /// <returns></returns>
        public CompanyLocationGroup GetAuthorization_ForACompanyLocationGroup(Guid professionalUserId, Guid companyLocationGroupId, out AuthorizationState authState, out bool isCompanyOwner)
        {
            authState      = AuthorizationState.NotAllowed;
            isCompanyOwner = false;
            Company company;
            CompanyLocationGroup companyLocationGroup = null;

            company = _companyQueries.GetCompanyFromOwnerUserGuid(professionalUserId.ToString());

            if (company != null)
            {
                // Owner - If it's the company owner, they have full rights.
                companyLocationGroup = _unitOfWork.CompanyLocationGroupsRepository.Get(i => i.CompanyLocationGroupId == companyLocationGroupId, includeProperties: "Company,CompanyLocations").FirstOrDefault();
                if (companyLocationGroup == null)
                {
                    companyLocationGroup = null;
                    authState            = AuthorizationState.CreateReadUpdate;
                }
                else if (companyLocationGroup != null && companyLocationGroup.Company != null && companyLocationGroup.Company.CompanyId == company.CompanyId)
                {
                    isCompanyOwner = true;
                    authState      = AuthorizationState.CreateReadUpdate;
                }
                else
                {
                    companyLocationGroup = null;
                    authState            = AuthorizationState.NotAllowed;
                }
            }
            else
            {
                // Employee - If it's an employee, they can view.
                company = _companyQueries.GetCompanyAndThisEmployeeFromEmployeeProfessionalUserId(professionalUserId.ToString());
                if (company != null)
                {
                    companyLocationGroup = _unitOfWork.CompanyLocationGroupsRepository.Get(i => i.CompanyLocationGroupId == companyLocationGroupId, includeProperties: "Company,CompanyLocations").FirstOrDefault();
                    if (companyLocationGroup != null && companyLocationGroup.Company != null && companyLocationGroup.Company.CompanyId == company.CompanyId)
                    {
                        authState = AuthorizationState.ReadOnly;
                    }
                    else
                    {
                        companyLocationGroup = null;
                        authState            = AuthorizationState.NotAllowed;
                    }
                }
            }

            // If it's anyone else, they can bugger off!
            return(companyLocationGroup);
        }
        private void AddOrUpdateCompanyLocationGroup(string userIdString, CompanyLocationGroup companyLocationGroup)
        {
            Guid userId = GuidHelper.GetGuid(userIdString);
            AuthorizationState authState            = AuthorizationState.NotAllowed;
            bool isCompanyOwner                     = false;
            List <CompanyLocationGroup> returnValue = new List <CompanyLocationGroup>();
            var  now      = DateTime.Now;
            bool isInsert = false;

            // do a separate check for access. This is the correct pattern.
            var existingClg = _accessQueries.GetAuthorization_ForACompanyLocationGroup(userId, companyLocationGroup.CompanyLocationGroupId, out authState, out isCompanyOwner);

            if (authState >= AuthorizationState.CreateReadUpdate)
            {
                // Is the CLG new?
                //var existingClg = _unitOfWork.CompanyLocationGroupsRepository.Get(i => i.CompanyLocationGroupId == companyLocationGroup.CompanyLocationGroupId,
                //                                                                                                    includeProperties: "CompanyLocations").FirstOrDefault();

                var submittingPro = _unitOfWork.ProfessionalsRepository.Get(i => i.ProfessionalUserId == userId).FirstOrDefault();

                if (existingClg == null)
                {
                    // New
                    isInsert = true;
                    var company = _companyQueries.GetCompanyFromOwnerUserGuid(userIdString);
                    companyLocationGroup.Company = company;
                    companyLocationGroup.CreatedByProfessional  = submittingPro;
                    companyLocationGroup.CreatedDate            = DateTime.Now;
                    companyLocationGroup.CompanyLocationGroupId = Guid.NewGuid();

                    if (companyLocationGroup.CompanyLocations != null)
                    {
                        foreach (var companyLocation in companyLocationGroup.CompanyLocations)
                        {
                            companyLocation.CreatedByProfessionalId = submittingPro.ProfessionalId;
                            companyLocation.CreatedDate             = now;
                            companyLocation.UpdatedByProfessionalId = submittingPro.ProfessionalId;
                            companyLocation.UpdatedDate             = now;
                            companyLocation.CompanyLocationId       = Guid.NewGuid();
                        }
                    }
                }
                else
                {
                    //UPDATE THE EXISTING CLG
                    existingClg.LocationGroupName = companyLocationGroup.LocationGroupName;

                    // CLG - has the deletion flag changed
                    if (!existingClg.IsDeleted && companyLocationGroup.IsDeleted)
                    {
                        existingClg.IsDeleted = companyLocationGroup.IsDeleted;
                        existingClg.DeletedByProfessionalId = submittingPro.ProfessionalId;
                        existingClg.DeletedDate             = DateTime.Now;
                    }
                    else if (existingClg.IsDeleted && !companyLocationGroup.IsDeleted)
                    {
                        existingClg.IsDeleted = companyLocationGroup.IsDeleted;
                        existingClg.DeletedByProfessionalId = null;
                        existingClg.DeletedDate             = null;
                    }

                    // UPDATE EACH CL
                    if (companyLocationGroup.CompanyLocations != null)
                    {
                        // stop null ref exceptions later.
                        if (existingClg.CompanyLocations == null)
                        {
                            existingClg.CompanyLocations = new List <CompanyLocation>();
                        }

                        // there will always be more than or equal num locations incoming than in the db as we don't allow deletions.
                        foreach (var companyLocation in companyLocationGroup.CompanyLocations)
                        {
                            // is the CL new?
                            var existingCLRow = existingClg.CompanyLocations.FirstOrDefault(i => i.CompanyLocationId == companyLocation.CompanyLocationId);
                            if (existingCLRow == null)
                            {
                                companyLocation.CompanyLocationId = Guid.NewGuid();
                                existingClg.CompanyLocations.Add(companyLocation);
                                companyLocation.CreatedByProfessionalId = submittingPro.ProfessionalId;
                                companyLocation.CreatedDate             = now;
                                companyLocation.UpdatedByProfessionalId = submittingPro.ProfessionalId;
                                companyLocation.UpdatedDate             = now;
                            }
                            else
                            {
                                // update
                                existingCLRow.UpdatedByProfessionalId             = submittingPro.ProfessionalId;
                                existingCLRow.UpdatedDate                         = now;
                                existingCLRow.IsProfessionalVisitToClientLocation = companyLocation.IsProfessionalVisitToClientLocation;
                                existingCLRow.Postcode = companyLocation.Postcode;
                                existingCLRow.IsPostCodeAreaAndDistrictOnly    = AddressHelper.IsPostCodeAreaAndDistrict(companyLocation.Postcode);
                                existingCLRow.IsPostCodeAreaDistrictSectorOnly = AddressHelper.IsPostCodeAreaDistrictSector(companyLocation.Postcode);
                                existingCLRow.AddressLine1 = companyLocation.AddressLine1;
                                existingCLRow.AddressLine2 = companyLocation.AddressLine2;
                                existingCLRow.TownCity     = companyLocation.TownCity;
                                existingCLRow.County       = companyLocation.County;

                                // have the CL deletion flags changed?
                                if (!existingCLRow.IsDeleted && companyLocation.IsDeleted)
                                {
                                    existingCLRow.IsDeleted = companyLocation.IsDeleted;
                                    existingCLRow.DeletedByProfessionalId = submittingPro.ProfessionalId;
                                    existingCLRow.DeletedDate             = DateTime.Now;
                                }
                                else if (existingCLRow.IsDeleted && !companyLocation.IsDeleted)
                                {
                                    existingCLRow.IsDeleted = companyLocation.IsDeleted;
                                    existingCLRow.DeletedByProfessionalId = null;
                                    existingCLRow.DeletedDate             = null;
                                }
                            }
                        }
                    }
                }

                // Do any of the locations have a mobile location?
                companyLocationGroup.HasProfessionalVisitsClientLocations = companyLocationGroup.CompanyLocations.FirstOrDefault(i => i.IsProfessionalVisitToClientLocation) != null;

                if (isInsert)
                {
                    _unitOfWork.CompanyLocationGroupsRepository.Insert(companyLocationGroup);
                }
                else
                {
                    //_unitOfWork.CompanyLocationGroupsRepository.Update(companyLocationGroup);
                }

                _unitOfWork.Save();
            }
        }