public async Task<ICommandResult> Handle(AdicionarUsuarioCommand command)
{
if (!EstaValido(command)) return Erro();
var idContrato = command.Admin ? command.ContratoId : _user.ObterContratoId();
var contratoAtual = await _contratoRepository.ObterPorId(idContrato);
var contratoUsuarioAtual = contratoAtual.Usuarios.FirstOrDefault(u => u.Email.Equals(command.Email));
var validacaoContrato = await ValidarInconsistenciaNoContratoUsuario();
if (validacaoContrato.Invalido)
return Erro(validacaoContrato.MensagemErro);
ContratoUsuario novoContratoUsuario = AdicionarUsuarioCommandFactory.ObterNovoContratoUsuario(command, contratoUsuarioAtual);
await AdicionarUsuarioContrato();
await AtualizarUsuarioContrato();
await LiberarSlotsDasEmpresasRevogadas();
PerfilAcesso perfilAcesso = await ObterPerfilAcessoParaAtualizarFirebase();
if (perfilAcesso is null)
return Erro(Shared.Enums.MensagemErro.PERFIL_ACESSO_NAO_ENCONTRADO);
var novasEmpresasPermitidas = AdicionarUsuarioCommandFactory.ObterNovasEmpresasPermitidas(contratoAtual, command);
if (!novasEmpresasPermitidas.Any())
return Erro(Shared.Enums.MensagemErro.USUARIO_EMPRESAS_NAO_ENCONTRADAS);
var ambienteAtual = await _ambienteRepository.ObterPrimeiroAmbientePorContratoId(idContrato);
await ModificarUsuarioAmbiente();
await ModificarUsuarioAmbienteFirebase();
return Resposta();
async Task<(bool Invalido, string MensagemErro)> ValidarInconsistenciaNoContratoUsuario()
{
if (contratoAtual is null)
return (true, MensagemErro.CONTRATO_NAO_ENCONTRADO);
if (!contratoAtual.Empresas.Exists(e => e.Cnpj.Equals(_user.ObterCnpj())))
return (true, Shared.Enums.MensagemErro.CONTRATO_EMPRESA_NAO_PERTENCENTE);
if (await _contratoRepository.ExisteUsuarioEmOutroContrato(idContrato, command.Email))
return (true, Shared.Enums.MensagemErro.EMAIL_JA_UTILIZADO_EM_OUTRO_CONTRATO);
if (contratoUsuarioAtual != null && !contratoUsuarioAtual.Id.Equals(command.Id))
return (true, Shared.Enums.MensagemErro.CONTRATO_USUARIO_JA_CADASTRADO_PARA_OUTRO_ID);
return (false, string.Empty);
}
async Task AdicionarUsuarioContrato()
{
if (contratoUsuarioAtual is not null) return;
await _contratoRepository.AdicionarUsuario(contratoAtual.Id, novoContratoUsuario);
}
async Task AtualizarUsuarioContrato()
{
if (contratoUsuarioAtual is null) return;
var usuarios = contratoAtual.Usuarios.ToList();
usuarios.Remove(contratoUsuarioAtual);
usuarios.Add(novoContratoUsuario);
await _contratoRepository.AtualizarUsuarios(contratoAtual.Id, usuarios);
}
async Task LiberarSlotsDasEmpresasRevogadas()
{
if (contratoUsuarioAtual is null) return;
RemoverDispositivosDesvinculoUsuarioEmpresaCommand commandRemoverDispositivos = new(contrato: contratoAtual,
empresasNovas: command.Empresas.ToList(),
novoContratoUsuario: novoContratoUsuario,
contratoRepository: _contratoRepository);
await commandRemoverDispositivos.Executar();
}
async Task<PerfilAcesso> ObterPerfilAcessoParaAtualizarFirebase()
{
if (!command.Admin)
return await _perfilAcessoRepository.ObterPorId(command.PerfilAcessoId);
command.Empresas = contratoAtual.Empresas.Select(e => e.Cnpj);
return await _perfilAcessoRepository.ObterPerfilAdministrador(idContrato);
}
async Task ModificarUsuarioAmbiente()
{
ambienteAtual.AdicionarUsuario(new AmbienteUsuario(command.Email, novasEmpresasPermitidas.Select(e => e.Cnpj).ToList(), perfilAcesso.Id));
await _ambienteRepository.AdicionarOuAtualizar(ambienteAtual);
}
async Task ModificarUsuarioAmbienteFirebase()
{
var factoryCards = ModulosCardFactory.ConstruirCards(await _moduloRepository.ObterModulos(), perfilAcesso);
var usuarioFireBase = await _usuarioFirebase.ObterUsuarioPorEmail(command.Email);
var informacoesLojasPermitidas = novasEmpresasPermitidas.Select(e => new UsuarioLoja(e.NomeFantasia, e.Cnpj)).ToList();
UsuarioAmbienteDto usuarioAmbiente = new(informacoesLojasPermitidas, factoryCards);
await _usuarioFirebase.AdicionarOuAtualizarUsuarioAmbiente(AdicionarUsuarioCommandFactory.ObterNovoUsuario(command, usuarioAmbiente, usuarioFireBase),
AdicionarUsuarioCommandFactory.ObterNovoUsuarioAmbiente(ambienteAtual, usuarioAmbiente, perfilAcesso));
}
}