O gerenciamento de informações e agilização de processos tornam-se cada vez mais importantes para uma empresa sobreviver em um mercado cada vez mais competitivo. Portanto, com base nisto, podemos dizer que um dos problemas mais visíveis encontrados em uma microempresa é a falta de um controle gerencial informatizado.

Neste artigo será apresentado o desenvolvimento de um sistema informatizado para gerenciamento de um salão de beleza e estará dividido em dois módulos: o primeiro é o módulo de cadastro e o segundo como agendamento, onde temos os dados de cadastro e controle dos clientes, serviços, profissionais e agendamento, facilitando o acesso as informações. Sendo assim, o sistema manterá um histórico onde serão registradas todas as movimentações sobre o cadastro dos clientes, serviços, profissionais e o agendamento dos serviços realizados.

Modelagem do Sistema

A modelagem do sistema foi baseada em quatro diagramas da UML (Linguagem de Modelagem Unificada): o diagrama de casos de uso, o diagrama de classes, o diagrama de objetos e o diagrama de atividades, além do banco de dados na linguagem SQL utilizando o Microsoft SQL Server.

Diagrama de Casos de Uso do sistema
Figura 1. Diagrama de Casos de Uso do sistema

O diagrama de casos de uso da Figura 1 procura, através de uma forma simples, demonstrar a interação do sistema com o usuário, resumindo o comportamento do sistema e seus atores, na qual podemos visualizar contextualmente como será utilizado o sistema. Nele constará as descrições por meio de uma linguagem bastante simples, como funções do caso de uso, quais atores irão interagir com ele, quais etapas devem ser executadas pelo ator e pelo sistema para que o caso de uso execute sua função, além de quais parâmetros deverão ser fornecidos e quais restrições e validações o caso de uso deve ter.

Diagrama de Classes
Figura 2. Diagrama de Classes

O diagrama de classes da Figura 2 tem por objetivo mostrar uma visão estática do sistema e o relacionamento das classes, definindo sua estrutura lógica, contendo elementos comportamentais solidificados, bem como restrições que o sistema tenha. Este diagrama apresenta uma visão de como as classes estão organizadas, preocupando-se em como definir a estrutura lógica das mesmas, sendo suas classes compostas por atributos e métodos no qual pode-se visualizar os relacionamentos e associações entre as classes.

Diagrama de Objetos
Figura 3. Diagrama de Objetos

O Diagrama de Objetos da Figura 3 fornece os possíveis valores armazenados pelos objetos em um determinado momento da execução de um processo do sistema, onde os objetos representam instâncias de classes. Este diagrama objetiva demonstrar a colaboração entre os objetos em um ponto do processamento de dados pelo software, realizando a simulação das possíveis situações derivadas das classes, enfocando partes das classes e suas funcionalidades.

Diagrama de Atividade - Visão Casos de Uso
Figura 4. Diagrama de Atividade - Visão Casos de Uso

Já o Diagrama de Atividades da Figura 4 descreve os passos ou ações e fluxo da aplicação baseados no diagrama de casos de uso deste projeto, mostrando a integração entre as ações e as mudanças de estado dos casos de uso envolvidos, no qual este diagrama enfatiza a sequência e condições para coordenar o comportamento dos casos de uso.

Banco de dados

Nas listagens a seguir criaremos um banco de dados no Microsoft SQL Server 2012, com as tabelas e suas chaves primárias e estrangeiras, onde as chaves primárias são utilizadas para controle das informações. Para não haver problemas de sobreposição de dados nas tabelas manteve-se o código para cada tabela com a função idendity, ou seja, não sendo possível gravar um dado na tabela com mesmo código, pois ele é único e auto incremento, então, para se obter um controle e segurança nas informações, o código de cada tabela foi colocado como chave primária. Já para chave estrangeira foram utilizadas as chaves primárias das tabelas que necessitem que suas informações sejam associadas a outras tabelas.

Na Listagem 1 temos o código de criação do banco. Repare que na última linha temos a configuração que define a ordem das partes de data (dia/mês/ano). Por padrão, o SQL salva as datas no formato ano/dia/mês. Essa configuração é usada apenas na interpretação de cadeias de caracteres e em como eles são convertidos em valores de data.Ele não tem nenhum efeito sobre a exibição desses valores.

A configuração de SET DATEFORMAT é definida somente no momento da execução e não no momento da análise.


Create DataBase BD_SYSBeauty;
go
use BD_SYSBeauty;
go
SET DATEFORMAT DMY;
Listagem 1. Banco de dados

Na Listagem 2 temos o código de criação da tabela cliente e posteriormente a inserção de dados para gerenciamento da tabela cliente pelo sistema.


  Create Table TBCliente (
    Cod int primary key identity(0,1), 
    Nome varchar(100) not null, 
    CPF varchar(11) , 
    data_nascimento datetime, 
    sexo varchar(13),  
    estado_civil varchar(12), 
    email varchar(255),
    observacoes varchar(255), 
    endereco varchar(255), 
    numero_end int, 
    CEP int, 
    bairro varchar(50), 
    cidade varchar(100), 
    estado varchar(30), 
    telefone varchar(10), 
    celular varchar(11)
  );
  insert into TBCliente (nome) values ('Sistema');
Listagem 2. Tabela Cliente

Para a tabela especialidades o código é pequeno, pois definimos apenas dois campos:


Create Table TBEspecialidades (Cod int primary key identity(0,1), 
Descricao varchar(50) not null
); 
insert into TBEspecialidades (Descricao) values ('Sistema');

Na Figura 5 temos o resultado do que será a tela de cadastro de especialidades

cadastro de especialidades
Figura 5. Cadastro de especialidades

Na Listagem 3 temos o código da tabela profissionais. Repare que aqui temos a chave secundária que pega as informações do campo código da tabela de especialidades.


  Create Table TBProfissional ( 
    Cod int primary key identity(0,1), 
    Nome varchar(255) not null,
    CPF varchar(11),
    data_nascimento smalldatetime,
    sexo varchar(13), 
    email varchar(255), 
    cod_especialidade int not null, 
    observacoes text,
    endereco varchar(255),
    numero_end int, 
    CEP varchar(8), 
    bairro varchar(50), 
    cidade varchar(100), 
    estado varchar(30), 
    telefone varchar(10), 
    celular varchar(11), 
    constraint fk_Especialidade foreign key (cod_especialidade) 
    references TBEspecialidades(Cod)
  );
  insert into TBProfissional (nome, cod_especialidade) 
  values ('Sistema', 0);
Listagem 3. Tabela de profissionais

Para a tabela de serviços, presente na Listagem 4, temos a chave secundária que pega informações da chave primária da tabela da Listagem 3.


  Create Table TBServico (
    Cod int primary key identity(0,1), 
    Nome varchar(255) not null,
    tipoServico varchar(150)not null,  
    TempoExecucao time not null,
    descricao varchar (255),
    valor money,
    observacoes varchar(255),
    cod_profissional int not null, 
    constraint fk_Profissional foreign key (cod_profissional) 
    references TBProfissional(Cod)
  );
   
  insert into TBServico (nome,tipoServico,TempoExecucao,cod_profissional) 
  values ('Sistema','Sistema','00:00',0);
Listagem 4. Tabela de serviços

O resultado dessa tabela será a tela apresentada na Figura 6.

Cadastro de serviços
Figura 6. Cadastro de Serviços

Na Listagem 5 temos a criação das duas tabelas de telefone, uma para clientes e a outra para profissionais, afinal de contas, num salão de beleza, a principal forma de contato com esses é através do telefone. Cada uma das tabelas tem uma chave secundária que pega informações da chave primária de sua respectiva tabela (cliente ou profissional).


  Create Table TBTelefones_Cli (
    Cod int primary key identity , 
    DDD int, 
    numero int, 
    tipo_telefone varchar(12), 
    cod_cliente int, cod_profissional int constraint fk_cod_cliente 
    foreign Key (cod_cliente) references TBCliente(Cod) 
  );
   
  Create Table TBTelefones_Prof (
    Cod int primary key identity , 
    DDD int, 
    numero int,
    tipo_telefone varchar(12), 
    cod_cliente int, cod_profissional int 
    constraint fk_cod_profissional foreign Key (cod_profissional) 
    references TBProfissional (Cod) 
  );
Listagem 5. Tabelas de telefone

A tela de cadastro de profissionais será a mesma da Figura 7.

Cadastro de profissionais
Figura 7. Cadastro de profissionais

Na Listagem 6 temos a tabela de agendamento, que terá várias chaves secundárias que pegará as informações de todas as tabelas criadas até o momento. Ao final temos o comando insert, que cuidará da inserção de data para carregamento do calendário pelo comando data grid view.


  Create Table TBAgendamento (
    cod int primary key identity,
    data_agendamento datetime not null, 
    horario_agendamento time not null,  
    cod_cliente int not null, 
    cod_profissional int not null,             
    observacoes varchar(255),
    cod_servico int  not null, 
    constraint fk_Cliente_agendamento foreign key (cod_cliente) 
    references TBCliente(Cod),  
    constraint fk_Profissional_agendamento foreign key 
    (cod_profissional) references TBProfissional(Cod), 
    constraint fk_Servico_agendamento foreign key 
    (cod_servico) references TBServico(Cod)
  );
  insert into TBAgendamento (data_agendamento, horario_agendamento, 
  cod_cliente, cod_profissional, cod_servico) 
  values ('01/01/1900', '00:00', 0, 0, 0)
Listagem 6. Tabela de agendamento

No código a seguir temos a criação da tabela de telas e o seu insert, responsável pela Linha de inserção das telas para criação do perfil de acesso do usuário por tela.


  Create Table TBTelas (cod int primary key identity, 
  tela varchar(255) not null);
  insert into TBTelas (tela) values ('mtUsuarios'), 
  ('mtPerfilAcesso'), ('mtProfis'), ('mtEspecialidade'), 
  ('mtCliente'),('mtServico'),('mtAgendamento');

Na Listagem 7 temos as tabelas de perfil e de usuário, responsáveis pela segurança do nosso banco, pois definimos aqui quem terá poderes de permissão para mexer no agendamento, além de quais telas terá acesso.


Create Table TBPerfil (cod int primary key identity(0,1), 
nome varchar(255) not null);
  Create Table TBPerfilAcesso (
    cod int primary key identity(0,1) , 
    cod_tela int not null, cod_perfil int not null, 
    permissao int not null constraint fk_perfilacesso_tela 
    foreign key (cod_tela) references TBTelas(Cod), 
    constraint fk_perfilacesso_perfil foreign key 
    (cod_perfil) references TBPerfil(Cod)
  );
  Create Table TBUsuario (
    Cod int primary key identity(0,1), 
    nome varchar(100) not null,
    login varchar(100),
    senha varchar(255) not null,
    tipoacesso int not null 
    constraint fk_tipoacesso_codPerfil foreign 
    key (tipoacesso) references TBPerfil(Cod) 
  );
Listagem 7. Tabelas de segurança

Para criar o usuário ADMIN de acesso restrito para desenvolvedores do sistema, visando futuras manutenções, podemos inserir os seguintes dados:


  insert into TBPerfil (nome) values ('_@@ADMIN');
  insert into TBPerfilAcesso (cod_tela,cod_perfil,permissao) 
  values (1,0,1),(2,0,1),(3,0,1),(4,0,1),(5,0,1),(6,0,1),(7,0,1)
  insert into TBUsuario (login,senha,nome,tipoacesso) 
  VALUES ('SYSBEAUTY','@bc12345','SysBeauty',0)

Para Inserção de dados via BD para criação de usuário administrativo para o sistema, para utilização do administrador do sistema e consequente primeiro acesso, podemos usar o código a seguir:


insert into TBPerfilAcesso (cod_tela,cod_perfil,permissao) 
values (1,3,1),(2,3,1),(3,3,1),(4,3,1),(5,3,1),(6,3,1),(7,3,1)
insert into TBUsuario (login,senha,nome,tipoacesso) 
VALUES ('ADMIN','@dmin','Administrador',0)

A tela de perfil de acesso ficará como mostra a Figura 8.

Tela de perfil de acesso
Figura 8. Tela de Perfil de acesso

Com todas as tabelas criadas, foi gerado o diagrama de dados (modelo relacional) pelo software Microsoft SQL Server, como podemos ver na Figura 9.

Modelo Relacional (lógico) Banco de Dados SQL
Figura 9. Modelo Relacional (lógico) Banco de Dados SQL

Neste modelo apresentado do banco de dados, as tabelas estão associadas para representar a inclusão dos dados, tendo como foco seguir a cardinalidade imposta para manter a integridade do modelo e auxiliando na inserção, alteração e exclusão dos dados. Este modelo consiste em uma coleção de tabelas e relação entre elas com seus nomes e chaves primárias e estrangeiras referentes a cada tabela e seu respectivo relacionamento.

Telas de acesso

As telas de acesso do sistema foram desenvolvidas no Visual Studio e seu código está escrito na linguagem C# onde serão descritas apenas suas principais funções e validações. Sendo parte da base de desenvolvimento do software, visando garantir a integridade e eficiência do código, assim como as informações a serem armazenadas no banco de dados.


private void btnLogin_Click(object sender, EventArgs e)
{
    string login = null;
    string senha = null;

    if (txtlogin.Text == "")
    {
        MessageBox.Show("Preencha o Campo LOGIN");
        return;
    }
    else if (txtsenha.Text == "")
    {
        MessageBox.Show("Preencha o Campo SENHA");
        return;
    }
    else
    {
        login = txtlogin.Text;
        senha = txtsenha.Text;
    }

    l.login = login;
    l.senha = senha;

    lDAL.Consultarlogin(l);

    if (Login.existe)
    {
        lDAL.ConsultarAcesso(l);

        this.Close();
    }
    else
    {
        MessageBox.Show("Usuário ou Senha Incorretas");
        return;
    }

}
Listagem 8. Código Validação Login e Senha

A Listagem 8 se refere as funções do botão de Login, que será usado para validar os campos de login e senha, visando evitar acessos indevidos ao sistema por usuários não cadastrados. Esta validação será realizada de modo que o login e senha estejam de acordo com os usuários registrados no sistema.


public static bool IsCpf(string cpf)
{
    int[] multiplicador1 = new int[9] { 10, 9, 8, 7, 6, 5, 4, 3, 2 };
    int[] multiplicador2 = new int[10] { 11, 10, 9, 8, 7, 6, 5, 4, 3, 2 };
    string tempCpf;
    string digito;
    int soma;
    int resto;
    cpf = cpf.Trim();
    cpf = cpf.Replace(".", "").Replace("-", "");
    if (cpf.Length != 11)
        return false;
    tempCpf = cpf.Substring(0, 9);
    soma = 0;

    for (int i = 0; i < 9; i++)
        soma += int.Parse(tempCpf[i].ToString()) * multiplicador1[i];
    resto = soma % 11;
    if (resto < 2)
        resto = 0;
    else
        resto = 11 - resto;
    digito = resto.ToString();
    tempCpf = tempCpf + digito;
    soma = 0;
    for (int i = 0; i < 10; i++)
        soma += int.Parse(tempCpf[i].ToString()) * multiplicador2[i];
    resto = soma % 11;
    if (resto < 2)
        resto = 0;
    else
        resto = 11 - resto;
    digito = digito + resto.ToString();
    return cpf.EndsWith(digito);
}
Listagem 9. Código de validação do campo CPF

A tela de cadastro de clientes ficará conforme mostra a Figura 10 e a tela de cadastro de usuários será igual a Figura 11.

Tela de cadastro de cliente
Figura 10. Tela de cadastro de cliente
Tela de cadastro de usuários
Figura 11. Tela de cadastro de usuários

A Listagem 9 tem como objetivo evitar que os dados preenchidos sejam incoerentes, garantindo assim a integridade das informações, pois o código verificará cada número do CPF buscando garantir que as informações sejam válidas, caso contrário não será permitida a inclusão de dados.


public static bool ValidaEmail(string Valor)
    {
        if (string.IsNullOrEmpty(Valor))
        {
            return true;
        }
        bool Valido = false;
        Regex regEx = new Regex(@"^[a-zA-Z][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]
        *[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$", RegexOptions.IgnoreCase);
        Valido = regEx.IsMatch(Valor);
        return Valido;
    }
Listagem 10. Código de validação do campo e-mail

O código de validação do campo e-mail da Listagem 10 busca evitar a inserção de dados incorretos para realizar cadastros, visando manter a concretude das informações registradas. Veja que o código faz uma verificação da formatação do e-mail realizando uma validação simples para inserção dos dados.


public mtAgendamento()
{
    InitializeComponent();
}

Agendamento agenda = new Agendamento();
Agendamento_DAL agendaDAL = new Agendamento_DAL();

int codcli, codpro, codser;
string nomecli, nomepro, descser;
bool nreg = false;

public bool Valida_Agenda()
{
    DateTime hoje = DateTime.Now.Date;

    if (dtdata.Value < hoje)
    {
        MessageBox.Show("Desculpe, por motivos de segurança, não é 
        possivel\neditar ou excluir agendamentos anteriores ao dia 
        de hoje: " + hoje);
        return true;
    }

    return false;
}

public void Carrega_Cal()
{

    mccalendario.TitleForeColor = System.Drawing.Color.Red;


    foreach (DataGridViewRow dataGridViewRow in dgvTudo.Rows)
    {

        object s = dataGridViewRow.Cells["data_agendamento"].Value;
        if (s.ToString() == "01/01/1900 00:00:00")
        {
            return;
        }

        string databruta = s.ToString();

        mccalendario.AddBoldedDate(DateTime.Parse(databruta));

    }

}


private void btn_Aplicar_Click(object sender, EventArgs e)
{


    DesignForm.Ativar_Todos(tsMenu);
    DesignForm.Aplicar_Cancelar(tsMenu);
    try
    {
        if (Validar())
        {
            MessageBox.Show("Por favor preencha todos os campos", 
            "Atenção", MessageBoxButtons.OK, MessageBoxIcon.Warning, 
            MessageBoxDefaultButton.Button1);
            if (!nreg)
            {
                DesignForm.Ativar_Todos(tsMenu);
                DesignForm.Novo_Remove(tsMenu);
                tsMenu.Items[1].Enabled = true;
            }
            else
            {
                DesignForm.Ativar_Todos(tsMenu);
                DesignForm.Novo_Remove(tsMenu);
            }
            return;
        }

        if (!nreg && Valida_Agenda())
        {
            return;
        }

        if (txtid.Text == "Automatico" || txtid.Text == "")
        {
            agenda.Id = 0;
        }
        else
        {
            agenda.Id = int.Parse(txtid.Text);
        }

        agenda.Data = DateTime.Parse(dtdata.Value.Date.ToString());
        agenda.Hora = txthora.Text;
        agenda.Obs = txtobs.Text;
        agenda.Cod_cliente = codcli;
        agenda.Cod_profissional = codpro;
        agenda.Cod_servico = codser;

        if (nreg)
        {
            agendaDAL.Cadastrar(agenda);
        }
        else
        {
            agendaDAL.Atualizar(agenda);
        }

        mtAgendamento_Load(sender, e);

        txtid.Text = "";
        txthora.Text = "";
        txtobs.Text = "";
        dtdata.Value = DateTime.Now.Date;
        lblcliente.Text = "-";
        lblprofissional.Text = "-";
        lblservico.Text = "-";
    }
    catch (Exception erro)
    {
        TelaErro tl = new TelaErro(erro.ToString());
        tl.ShowDialog();

        return;
    }
}
Listagem 11. Código para realizar agendamento

Na Listagem 11 será realizada verificação dos campos necessários para salvar o agendamento. Primeiramente temos a função Valida_Agenda(), responsável pela validação da data de agendamento do sistema, não permitindo a exclusão ou alteração anterior à data de agendamento. Já a função Carrega_Cal() é responsável pelo carregamento do data grid view no qual será apresentado o calendário para escolha das datas. Consequentemente, para aplicação ou salvamento dos dados no BD, o código se refere as funções do botão Aplicar (Salvar) que passa por uma validação simples para verificar se todos os campos estão preenchidos, em seguida analisa a agenda verificando se não há nenhum agendamento anterior à data agendada. Caso seja um novo cadastro, ele passará por uma verificação e aplicará junto ao método cadastrar a inclusão do agendamento no banco de dados.

Na Figura 12 você confere como ficou a tela de agendamento.
Tela de agendamento
Figura 12. Tela de agendamento

Sendo assim, podemos concluir que a aplicação deste projeto auxiliará na otimização de uso dos recursos e dados disponíveis para gerenciamento eficaz das informações contidas no banco de dados, disponibilizando ao usuário uma experiência de usabilidade agradável e de fácil entendimento, no qual o mesmo poderá acessar as informações de forma simples, segura e ergonômica.


Referências Bibliográficas

  • BEZERRA, Eduardo. Princípios de Análise e Projeto de Sistemas com UML; Rio de Janeiro, Campus Ed., 2006.
  • CARDOSO, Virgínia. Linguagem SQL: fundamentos e práticas / Virgínia Cardoso, Giselle Cardoso. Saraiva, 2013.
  • GUEDES, Gilleanes T. A. UML 2 – Uma Abordagem Prática. 2.ed. Novatec, 2011.
  • SILVA, Alberto Manuel Rodrigues da Silva. UML – Metodologias e Ferramentas Case / Alberto Manuel Rodrigues da Silva, Carlos Alberto Escaleira Videira. 1.ed. Centro Atlântico, 2001.
  • SEABRA, João. UML – Unified Modeling Language: Uma ferramenta para o Design de Software. Ciência Moderna, 2013.
  • STELLMAN, Andrew. Use a Cabeça C# / Andrew Stellman, Jennifer Greene; [tradução Eveline Machado]. 2.ed. Alta Books, 2011.
  • BETIOL, Adriana Holtz. Avaliação de usabilidade para os computadores de mão: um estudo comparativo entre três abordagens para ensaios de interação. 2004. 210f. Tese (Doutorado em Engenharia de Produção) – Programa de Pós-Graduação em Engenharia de Produção, UFSC, Florianópolis.