public async Task <ActionResult> Edit(BOAccountEditViewModel model)
        {
            ViewBag.Empresas = _Empresas;

            for (int i = 0; i < model.EmpresasGrupos.Count; i++)
            {
                model.EmpresasGrupos[i].PerfilImpressora = PerfilImpressorasList(model.EmpresasGrupos[i].IdEmpresa, idPerfilImpressora: model.EmpresasGrupos[i].IdPerfilImpressoraPadrao);
            }

            ViewResult errorView()
            {
                return(View(model));
            }

            if (!ModelState.IsValid)
            {
                return(errorView());
            }

            ApplicationUser user = await UserManager.FindByNameAsync(model.UserName).ConfigureAwait(false);

            if (user == null)
            {
                throw new HttpException(404, "Not found");
            }

            if (model.EmpresasGrupos.Any(x => x.IdPerfilImpressoraPadrao == null))
            {
                ModelState.AddModelError(nameof(model.EmpresasGrupos), "Selecione um Perfil de Impressão Padrão em todas as empresas.");
                return(errorView());
            }

            var existingUserByEmail = await UserManager.FindByEmailAsync(model.Email).ConfigureAwait(false);

            if (existingUserByEmail != null && existingUserByEmail.Id != user.Id)
            {
                ModelState.AddModelError(nameof(model.Email), Res.UserEmailAlreadyExistsMessage);
                return(errorView());
            }

            if (model.EmpresasGrupos.NullOrEmpty())
            {
                ModelState.AddModelError(nameof(model.EmpresasGrupos), Res.RequiredOnlyCompany);
                return(errorView());
            }

            if (!model.EmpresasGrupos.All(w => w.Grupos.Any(a => a.IsSelected)))
            {
                ModelState.AddModelError(nameof(model.EmpresasGrupos), Res.RequiredOnlyGroup);
                return(errorView());
            }

            if (!model.EmpresasGrupos.Any(w => w.IsEmpresaPrincipal))
            {
                ModelState.AddModelError(nameof(model.EmpresasGrupos), "Selecione a empresa principal do usuário.");
                return(errorView());
            }

            for (int i = 0; i < model.EmpresasGrupos.Count; i++)
            {
                if (model.EmpresasGrupos[0].CorredorEstoqueInicio == null && model.EmpresasGrupos[0].CorredorEstoqueFim != null)
                {
                    ModelState.AddModelError($"[{i}].CorredorEstoque", "Preencha o valor inicial do Corredor Estoque");
                }

                if (model.EmpresasGrupos[0].CorredorEstoqueInicio != null && model.EmpresasGrupos[0].CorredorEstoqueFim == null)
                {
                    ModelState.AddModelError($"[{i}].CorredorEstoque", "Preencha o valor final do Corredor Estoque");
                }

                if (model.EmpresasGrupos[0].CorredorEstoqueInicio.HasValue && model.EmpresasGrupos[0].CorredorEstoqueFim.HasValue)
                {
                    if (model.EmpresasGrupos[0].CorredorEstoqueInicio.Value > model.EmpresasGrupos[0].CorredorEstoqueFim.Value)
                    {
                        ModelState.AddModelError($"[{i}].CorredorEstoque", "O valor inicial do Corredor Estoque não pode ser maior do que o final");
                    }
                }

                if (model.EmpresasGrupos[0].CorredorSeparacaoInicio == null && model.EmpresasGrupos[0].CorredorSeparacaoFim != null)
                {
                    ModelState.AddModelError($"[{i}].CorredorSeparacao", "Preencha o valor inicial do Corredor Separação");
                }

                if (model.EmpresasGrupos[0].CorredorSeparacaoInicio != null && model.EmpresasGrupos[0].CorredorSeparacaoFim == null)
                {
                    ModelState.AddModelError($"[{i}].CorredorSeparacao", "Preencha o valor final do Corredor Separação");
                }

                if (model.EmpresasGrupos[0].CorredorSeparacaoInicio.HasValue && model.EmpresasGrupos[0].CorredorSeparacaoFim.HasValue)
                {
                    if (model.EmpresasGrupos[0].CorredorSeparacaoInicio.Value > model.EmpresasGrupos[0].CorredorSeparacaoFim.Value)
                    {
                        ModelState.AddModelError($"[{i}].CorredorSeparacao", "O valor inicial do Corredor Separação não pode ser maior do que o final");
                    }
                }
            }

            if (!ModelState.IsValid)
            {
                return(errorView());
            }

            ApplicationUser oldUser = Mapper.Map <ApplicationUser>(user);

            user.Email = model.Email;

            var empresasGruposNew = new StringBuilder();
            var empresasGruposOld = new StringBuilder();

            var companiesUser = _unitOfWork.UsuarioEmpresaRepository.GetAllEmpresasByUserId(user.Id);
            var empresas      = Empresas.Where(w => companiesUser.Contains(w.IdEmpresa)).ToList();

            foreach (var empresa in empresas)
            {
                IList <string> selectedRoles = await UserManager.GetUserRolesByIdEmpresa(user.Id, empresa.IdEmpresa).ConfigureAwait(false);

                if (selectedRoles.Any())
                {
                    empresasGruposOld.AppendLine(string.Format("{0}: {1}", empresa.Nome, string.Join(", ", selectedRoles.ToArray())));
                    empresasGruposOld.AppendLine(" || ");
                }
            }

            foreach (var item in model.EmpresasGrupos.Where(x => x.Grupos.Any(y => y.IsSelected)))
            {
                IEnumerable <string> selectedRoles      = item.Grupos.Where(x => x.IsSelected).Select(x => x.Name);
                IList <string>       rolesUsuarioEdicao = await UserManager.GetUserRolesByIdEmpresa(user.Id, item.IdEmpresa).ConfigureAwait(false);

                IList <string> rolesUsuarioLogado = await UserManager.GetUserRolesByIdEmpresa(User.Identity.GetUserId(), item.IdEmpresa).ConfigureAwait(false);

                IEnumerable <string> rolesIgnorar = rolesUsuarioEdicao.Where(x => !rolesUsuarioLogado.Any(y => y == x) && !rolesUsuarioLogado.Contains("Administrador"));


                empresasGruposNew.AppendLine(string.Format("{0}: {1}", item.Nome, string.Join(", ", selectedRoles.ToArray())));
                empresasGruposNew.AppendLine(" || ");
                IdentityResult result = await UserManager.UpdateAsync(user, selectedRoles, rolesIgnorar, item.IdEmpresa).ConfigureAwait(false);

                if (!result.Succeeded)
                {
                    throw new InvalidOperationException(Resources.CommonStrings.RequestUnexpectedErrorMessage);
                }
            }

            var oldPerfil = _unitOfWork.PerfilUsuarioRepository.GetById(model.PerfilUsuarioId);

            var perfilUsuario = _unitOfWork.PerfilUsuarioRepository.GetById(model.PerfilUsuarioId);

            perfilUsuario.Nome           = model.Nome;
            perfilUsuario.EmpresaId      = model.EmpresasGrupos.Where(w => w.IsEmpresaPrincipal).First().IdEmpresa;
            perfilUsuario.Departamento   = model.Departamento;
            perfilUsuario.DataNascimento = model.DataNascimento;
            perfilUsuario.Cargo          = model.Cargo;
            perfilUsuario.Ativo          = model.Ativo;

            _boService.EditPerfilUsuario(perfilUsuario);

            var empresasGrupos = model.EmpresasGrupos.Where(w => w.Grupos.Any(a => a.IsSelected))
                                 .Select(s => new BOAccountService.UsuarioEmpresaUpdateFields {
                IdEmpresa = s.IdEmpresa, IdPerfilImpressoraPadrao = s.IdPerfilImpressoraPadrao, CorredorEstoqueInicio = s.CorredorEstoqueInicio, CorredorEstoqueFim = s.CorredorEstoqueFim, CorredorSeparacaoInicio = s.CorredorSeparacaoInicio, CorredorSeparacaoFim = s.CorredorSeparacaoFim
            }).ToList();

            _boService.EditUsuarioEmpresas(Empresas, empresasGrupos, user.Id, perfilUsuario.PerfilUsuarioId);

            var userInfo = new BackOfficeUserInfo();

            Notify.Success(Resources.CommonStrings.RegisterEditedSuccessMessage);
            return(RedirectToAction("Index"));
        }
        public async Task <ActionResult> Edit(string id)
        {
            ViewBag.Empresas = _Empresas;

            ApplicationUser user = await UserManager.FindByNameAsync(id).ConfigureAwait(false);

            if (user == null)
            {
                throw new HttpException(404, "Not found");
            }

            var empresas = _unitOfWork.UsuarioEmpresaRepository.GetAllEmpresasByUserId(user.Id);

            empresas = Empresas.Where(w => empresas.Contains(w.IdEmpresa)).Select(s => s.IdEmpresa).ToList();

            var usuarioEmpresas = _unitOfWork.UsuarioEmpresaRepository.Tabela().Where(x => x.UserId == user.Id).ToList();

            var perfil = _unitOfWork.PerfilUsuarioRepository.GetByUserId(user.Id);

            var model = new BOAccountEditViewModel
            {
                Ativo           = perfil.Ativo,
                Cargo           = perfil.Cargo,
                DataNascimento  = perfil.DataNascimento,
                Departamento    = perfil.Departamento,
                PerfilUsuarioId = perfil.PerfilUsuarioId,
                Nome            = perfil.Nome,
                Email           = user.Email,
                UserName        = user.UserName
            };

            foreach (long empresa in empresas)
            {
                var usuarioEmpresa = usuarioEmpresas.FirstOrDefault(x => x.IdEmpresa == empresa);

                var empGrupos = new EmpresaGrupoViewModel
                {
                    IdEmpresa                = empresa,
                    Nome                     = Empresas.First(f => f.IdEmpresa == empresa).Nome,
                    IsEmpresaPrincipal       = perfil.EmpresaId == empresa ? true : false,
                    IdPerfilImpressoraPadrao = usuarioEmpresa?.IdPerfilImpressoraPadrao,
                    PerfilImpressora         = PerfilImpressorasList(empresa, usuarioEmpresa?.IdPerfilImpressoraPadrao),
                    CorredorEstoqueInicio    = usuarioEmpresa?.CorredorEstoqueInicio,
                    CorredorEstoqueFim       = usuarioEmpresa?.CorredorEstoqueFim,
                    CorredorSeparacaoInicio  = usuarioEmpresa?.CorredorSeparacaoInicio,
                    CorredorSeparacaoFim     = usuarioEmpresa?.CorredorSeparacaoFim,
                };

                List <string> gruposPermissoesUsuarioEdicao = (await UserManager.GetUserRolesByIdEmpresa(user.Id, empresa).ConfigureAwait(false)).OrderBy(x => x).ToList();
                List <string> gruposPermissoesUsuarioLogado = (await UserManager.GetUserRolesByIdEmpresa(User.Identity.GetUserId(), empresa).ConfigureAwait(false)).OrderBy(x => x).ToList();

                if (gruposPermissoesUsuarioLogado.Contains("Administrador"))
                {
                    List <string> todosGrupos = RoleManager.Roles.OrderBy(x => x.Name).Select(x => x.Name).ToList();

                    foreach (var grupoPermissaoUsuario in todosGrupos)
                    {
                        var groupItemViewModel = new GroupItemViewModel
                        {
                            IsSelected = gruposPermissoesUsuarioEdicao.Any(x => x == grupoPermissaoUsuario),
                            Name       = grupoPermissaoUsuario
                        };

                        empGrupos.Grupos.Add(groupItemViewModel);
                    }
                }
                else
                {
                    var gruposPermissoesSemelhantes = gruposPermissoesUsuarioEdicao.Where(x => gruposPermissoesUsuarioLogado.Contains(x)).ToList();

                    foreach (var grupoPermissaoUsuario in gruposPermissoesSemelhantes)
                    {
                        var groupItemViewModel = new GroupItemViewModel
                        {
                            IsSelected = true,
                            Name       = grupoPermissaoUsuario
                        };

                        empGrupos.Grupos.Add(groupItemViewModel);
                    }
                }

                empGrupos.Grupos.OrderBy(x => x.Name);

                model.EmpresasGrupos.Add(empGrupos);
            }

            return(View(model));
        }