Este documento descreve o desenvolvimento de uma interface gráfica para gestão de uma agência de viagens nacional. O sistema permite inserir, alterar e listar dados de clientes, autocarros, atividades, viagens e reservas. Além disso, fornece estatísticas e automatismos como a geração de códigos e atribuição de autocarros a atividades.
Controlador de ganho automático baseado numa plataforma FPGA
Uma interface gráfica para gestão de uma agência de viagens
1. Instituto Politécnico do Cávado e do Ave
Escola Superior de Tecnologia
Engenharia Eletrotécnica e de Computadores
Interface gráfico para gestão de uma
agência de viagens
Paulo Lima
Janeiro de 2014
2. ii
Agradecimentos
Gostaria de agradecer em primeiro lugar ao Doutor João Carlos Silva, pela
orientação neste trabalho e pelo seu papel ativo na minha formação ao longo de duas
unidades curriculares.
Expresso uma nota de gratidão ao Doutor Duarte Duque, que lecionou a primeira
unidade curricular na área de programação e tão bem forneceu as bases de
desenvolvimento algorítmico.
Por último, agradecemos à minha família todo o apoio prestado e compreensão,
uma vez que grande parte deste trabalho se desenvolveu durante um período festivo
com alguns sacrifícios pessoais.
A todos, muito obrigado!
3. iii
Resumo
Neste trabalho, pretendia-se o desenvolvimento de uma interface gráfica com o
utilizador que permitisse a gestão de uma agência de viagens nacionais. A solução
adotada foi dividir o problema em classes, sendo que cada classe corresponde a uma
das variáveis do problema. Dentro das classes foram definidas propriedades para
acesso e alteração dos dados.
Em seguida foram desenvolvidos os menus de interface para permitir ao
utilizador inserir, alterar, listar e apagar dados, tais como clientes, autocarros,
atividades, viagens e reservas.
O sistema foi desenvolvido para ser automático a determinados níveis,
nomeadamente na geração dos códigos (clientes, autocarros, viagens e reservas) e na
atribuição dos autocarros por atividade. Assim, para satisfazer uma série de critérios,
que deixavam de fazer sentido no contexto desenvolvido, foi criado o menu
“Estatísticas” que permite, por exemplo, verificar se poderia ser marcada uma
atividade com um autocarro num determinado período, caso o sistema não fosse
automático.
Finalmente todo o Software foi revisto de modo a prever possíveis bugs e foram
criados mecanismos de proteção.
Palavras-Chave (Tema): Interface gráfica, Linguagens de programação.
Palavras-Chave (Tecnologias): Visual Studio, C#, Microsoft.NET.
“Uma caminhada de mil léguas começa com o primeiro passo, diz o filósofo...
int main() { , diz o programador…”
Pensamento anónimo
4. iv
Índice
Agradecimentos ............................................................................................................................ ii
Resumo......................................................................................................................................... iii
Índice.............................................................................................................................................iv
1 Introdução ............................................................................................................................ 1
1.1 Enquadramento............................................................................................................. 1
1.2 Apresentação do trabalho............................................................................................. 1
1.3 Objetivos ....................................................................................................................... 2
1.4 Planeamento do trabalho ............................................................................................. 3
1.5 Tecnologias utilizadas.................................................................................................... 3
1.5.1 Microsoft.NET........................................................................................................ 3
1.5.2 Microsoft.NET Framework .................................................................................... 4
1.5.3 Linguagem de programação C#............................................................................. 4
1.6 Contributos deste trabalho........................................................................................... 5
2 Descrição Técnica ................................................................................................................. 6
2.1 Estudo do problema...................................................................................................... 6
2.1.1 Clientes.................................................................................................................. 6
2.1.2 Autocarros............................................................................................................. 7
2.1.3 Atividades.............................................................................................................. 7
2.1.4 Viagens .................................................................................................................. 8
2.1.5 Reservas ................................................................................................................ 9
2.1.6 Histórico .............................................................................................................. 10
2.2 Construção das classes................................................................................................ 11
2.2.1 Classe Cliente ...................................................................................................... 11
2.2.2 Classe Autocarro.................................................................................................. 12
2.2.3 Classe Atividade .................................................................................................. 13
5. v
2.2.4 Classe Viagem...................................................................................................... 14
2.2.5 Classe Reserva..................................................................................................... 15
2.2.6 Classe Agência..................................................................................................... 16
2.2.7 Classe Program.................................................................................................... 17
2.3 Implementação dos interfaces gráficos ...................................................................... 18
2.3.1 MenuStrip............................................................................................................ 18
2.3.2 Label .................................................................................................................... 19
2.3.3 Button.................................................................................................................. 19
2.3.4 TextBox................................................................................................................ 19
2.3.5 DataGridView ...................................................................................................... 20
2.3.6 ComboBox ........................................................................................................... 20
2.3.7 DateTimePicker ................................................................................................... 20
2.3.8 RadioButton ........................................................................................................ 21
2.3.9 PictureBox ........................................................................................................... 21
2.4 Algoritmos desenvolvidos ........................................................................................... 21
2.4.1 Propriedades ....................................................................................................... 22
2.4.2 Métodos de instância.......................................................................................... 22
2.4.3 Geração automática de códigos.......................................................................... 23
2.4.4 Verificação do código da atividade ..................................................................... 23
2.4.5 Cálculo da diferença entre dias........................................................................... 24
2.4.6 Automatismos e mecanismos de controlo.......................................................... 25
2.5 Outros trabalhos ......................................................................................................... 25
3 Testes e Resultados............................................................................................................ 27
4 Conclusões.......................................................................................................................... 32
5 Referências Bibliográficas................................................................................................... 33
6. 1
1 Introdução
1.1 Enquadramento
Uma aplicação informática desenvolvida para um fim comercial, é quanto mais
rica, quanto a qualidade do seu ambiente gráfico. Este deve ser apelativo e indicar
claramente o objetivo de cada função.
Utilizando o C# no desenvolvimento de soluções, agrega-se a vantagem da
utilização de uma ferramenta poderosa com um ambiente gráfico apelativo. A mesma
solução poderia ser desenvolvida numa linguagem sem estas caraterísticas, como por
exemplo o C, mas levaria a uma solução com muito mais código fonte a desenvolver e
uma qualidade visual inferior. Uma solução baseada em C torna-se também demasiado
morosa de executar para o utilizador, uma vez que as instruções de interface são
executadas uma a uma, enquanto o C# permite a realização de múltiplas instruções
simultâneas com apenas um click (por exemplo introduzir todos os dados de um
cliente na base de dados).
Assim, ao pretender-se desenvolver um interface gráfico com o utilizador para
um sistema de gestão de uma agência de viagens, a escolha recaiu na utilização do C#
como Software de programação que permite a criação de uma aplicação que pode ser
utilizada em qualquer computador com ambiente Windows dotado de Microsoft.NET
Framework.
1.2 Apresentação do trabalho
O trabalho tem como objetivo consolidar os conhecimentos adquiridos ao longo
das duas unidades curriculares anteriores sobre paradigmas de programação,
utilizando como base o paradigma da programação orientada a objetos. Para tal, é
proposto um problema real que deverá ser solucionado através da linguagem de
programação C#.
O problema a resolver, consiste numa agência de viagens que pretende uma
aplicação para gestão de viagens nacionais, considerando os seguintes requisitos:
A agência oferece um determinado conjunto de viagens nacionais;
7. Introdução
2
Cada viagem é constituída por um código, descrição, preço base e um
programa consistindo num conjunto de atividades distribuídas ao longo de
um determinado período;
Cada atividade tem um código único (alfanumérico), descrição, preço e
número de clientes inscritos. A realização de uma determinada atividade
poderá implicar a utilização de autocarros;
A instituição disponibiliza de um determinado conjunto de autocarros,
sendo que cada um possui um código único e uma determinada capacidade;
Aquando da reserva de uma determinada viagem por um cliente, o mesmo
poderá indicar quais as atividades que pretende realizar, sendo que cada
cliente deverá possuir um código único, nome, morada e histórico das
viagens realizadas.
A aplicação desenvolvida deverá implementar uma interface gráfica com o
utilizador e todos os dados da aplicação deverão ficar armazenados de
forma permanente em ficheiros.
1.3 Objetivos
1. Inserção, remoção e alteração de viagens, atividades e autocarros;
2. Dada uma viagem, um dia e um horário, agendar uma atividade para esse
horário (dependendo da atividade pode ser ou não necessário reservar
autocarros);
3. Listar todos os dados de uma determinada viagem;
4. Registar a reserva de determinada viagem por um cliente com indicação das
atividades escolhidas. A operação deverá apresentar o preço final da
viagem a cobrar ao cliente;
5. Listar todos os dados de uma viagem reservada por um cliente;
6. Dado um autocarro e uma determinada hora de um dia, determinar qual a
atividade agendada para essa hora;
7. Dado um autocarro e um determinado dia, mostrar todas as atividades
envolvendo o autocarro e agendadas para esse dia;
8. Dado um autocarro e um dia, determinar a taxa de utilização do autocarro
nesse dia, considerando o período das 8:00 até às 24:00;
8. Introdução
3
9. Dados dois autocarro e um dia D, determinar quais os períodos de tempo
em que ambos os autocarros não têm nenhuma atividade agendada;
10. Dados dois autocarros, um dia e um período de tempo, determinar uma
lista de horários possíveis para marcar uma atividade com os dois
autocarros.
1.4 Planeamento do trabalho
1. Estudo do problema;
2. Breve pesquisa sobre a biblioteca Windows Forms;
3. Desenho do diagrama de blocos do sistema;
4. Construção das classes;
5. Implementação dos interfaces/algoritmos;
6. Escrita do relatório final.
1.5 Tecnologias utilizadas
1.5.1 Microsoft.NET
Trata-se de uma plataforma de Software que permite conectar informações,
sistemas, pessoas e dispositivos, ou seja, permite efetuar a conexão entre uma grande
variedade de tecnologias quer sejam de âmbito de utilização pessoal, quer relativas a
negócios ou outro tipo de servidor, pelo que permite o acesso rápido e eficaz a
informações importantes em qualquer lugar.
Foi desenvolvida através dos padrões do XML Web Services pelo que possibilita
que diversos sistemas liguem os seus dados e as transações são efetuadas
independentemente do sistema operativo, computador e linguagem de programação
utilizados.
A grande vantagem da utilização do Microsoft.NET reside no facto deste
promover uma excelente capacidade de desenvolver, implementar, gerir e utilizar as
soluções conectadas através do XML Web Services de forma célere, com poucos custos
e de forma bastante segura.
9. Introdução
4
1.5.2 Microsoft.NET Framework
Esta aplicação pode ser distinguida através de três fragmentos, entre os quais o
CLR (Common Language Runtime) que é responsável por executar o interface entre o
sistema operativo e o código desenvolvido.
Através do CLR o compilador gera um código que pode ser adaptado a qualquer
sistema operativo. Todas as linguagens de programação que utilizam a tecnologia
Microsoft.NET possuem as mesmas classes presentes na Framework selecionada. Por
fim, o ASP.NET fornece acesso direto a linguagens de programação orientadas a
objetos como o Visual Basic ou o C#.
Qualquer linguagem de programação que utilize a tecnologia Microsoft.NET
realiza um processo de compilação similar. Quando um código é compilado para uma
linguagem intermediária, MSIL (Microsoft Intermediate Language), o ficheiro gerado é
denominado Assembly e poderá ter dois géneros de extensões: EXE ou DLL. Assim,
quando um ficheiro é executado, o programa é convertido em código máquina de
forma a correr no sistema operativo em que o CRL está inserido. Posto isto, o MSIL
permite gerar o mesmo ficheiro binário para qualquer plataforma que possua o CLR
que por sua vez tem a função de converter este arquivo para código máquina
compatível com o sistema operativo utilizado.
1.5.3 Linguagem de programação C#
Esta linguagem faz parte do conjunto de ferramentas fornecidas através da
plataforma Microsoft.NET e é caracterizada pela sua simplicidade e robustez. Além de
ser um tipo de programação orientada a objetos, é também bastante versátil na
medida em que a sua execução pode ser efetuada em inúmeros dispositivos de
Hardware, não apenas em PC mas também em qualquer dispositivo móvel.
O C# surgiu devido ao facto de se ter verificado um grande avanço no que
concerne, tanto às ferramentas de programação como aos dispositivos eletrónicos, o
que levou a novos desafios e exigências, pois com o surgimento de alguns dispositivos
mais sofisticados, estes revelaram-se incompatíveis com o Software mais antigo.
Durante o desenvolvimento desta plataforma Microsoft.NET, as bibliotecas
foram redigidas através de uma linguagem denominada SMC (Simple Managed C) que
10. Introdução
5
possuía, então, um compilador próprio para o seu desenvolvimento. Em 1999 dá-se o
início do desenvolvimento da linguagem Cool, sendo que cerca de um ano mais tarde,
o projeto Microsoft.NET seria apresentado ao público e a linguagem anteriormente
denominada Cool passou a ser denominada C#.
1.6 Contributos deste trabalho
Atualmente, uma elevada percentagem da tecnologia utilizada é programada ou
a nível de Software (programas informáticos, microcontroladores, entre outros) ou a
nível de Hardware (FPGA, PLC, entre outros). Assim, torna-se imperativo dominar os
conhecimentos na área de programação bem como manipular os diferentes
paradigmas associados a cada linguagem.
Ao se desenvolver este trabalho, não só se pôs em prática os conhecimentos
adquiridos ao longo da unidade curricular juntamente com todos os conhecimentos
adquiridos previamente, como se produziu uma aplicação final que podia ser
empregue a nível comercial, após os devidos ajustes que o cliente final pretendesse.
11. 6
2 Descrição Técnica
2.1 Estudo do problema
Após um estudo inicial, decidiu-se que o sistema deveria apresentar duas
camadas de dados: estáticos e dinâmicos.
Os dados estáticos seriam aqueles que o utilizador do sistema seria responsável
por carregar tais como dados de clientes, autocarros, atividades e viagens.
Os dados dinâmicos seriam todos os dados produzidos aquando da realização de
uma reserva por um cliente e não poderiam ser manipulados pelo utilizador, uma vez
que o sistema será programado para atuar de forma automática.
Figura 1 – Diagrama de blocos do sistema.
2.1.1 Clientes
Um cliente será qualquer indivíduo inscrito na agência, quer efetue ou não
alguma reserva de viagem. As operações a realizar neste bloco serão:
Inserir um novo cliente;
Listar todos os clientes inscritos;
Alterar os dados de um cliente;
Apagar um cliente.
12. Descrição Técnica
7
2.1.2 Autocarros
Definiu-se que os autocarros utilizados pela agência serão provenientes de uma
agência de Rent-A-Car, sendo que por questões de segurança e manutenção, ao fim de
100 horas de utilização deixam de estar disponíveis para participar em novas
atividades, sendo devolvidos à empresa de aluguer.
Quando um autocarro passa ao estado inativo, continua no sistema para poder
ser consultado o seu histórico, mas o sistema automático não o contabiliza para a
marcação de atividades. O utilizador pode, se quiser, removê-lo manualmente.
Foi considerado que o tipo de lotação para estes autocarros, pode ser alterado,
mediante um pedido efetuado à empresa de aluguer.
As operações a realizar neste bloco serão:
Inserir um novo autocarro;
Listar todos os autocarros no sistema;
Alterar a lotação de um autocarro;
Apagar um autocarro.
2.1.3 Atividades
As atividades, correspondem a um pacote de escolhas que cada cliente poderá
ou não selecionar em cada viagem que efetue, uma vez que são opcionais.
Existem dois tipos de atividades: aquelas que decorrem no local da viagem e não
necessitam transporte e outras que devido à deslocação necessitam de marcação de
autocarros.
Para este bloco foi necessário tomar duas decisões importantes:
Uma atividade inicia e termina dentro do mesmo dia;
Quando um autocarro é selecionado para uma atividade, este, deixa de
estar disponível para outra atividade no mesmo dia.
A justificação para um autocarro só poder estar selecionado para uma atividade
em cada dia, apesar de parecer pouco eficiente é lógica, uma vez que se ele for
escalado para uma atividade no Porto das 10:00 as 11:00, fisicamente não poderia
13. Descrição Técnica
8
estar no Algarve para uma atividade as 12:00. E não obstante, é necessário contar com
o tempo de limpeza e preparação do autocarro entre atividades.
As operações a realizar neste bloco serão:
Inserir uma nova atividade;
Listar todas as atividades no sistema;
Alterar uma atividade;
Apagar uma atividade.
A opção alterar atividade vai permitir mudar o preço e a lotação de determinada
atividade. Se a atividade necessitar de autocarro e a lotação for alterada podem surgir
três situações:
Número de autocarros marcados insuficiente;
Número de autocarros marcados ajustado;
Número de autocarros marcados em excesso.
Devido à previsão desta situação, o sistema irá calcular o número de autocarros a
atribuir à nova lotação e marcar/desmarcar autocarros conforme a necessidade. Caso
o sistema não possua autocarros de momento para satisfazer um aumento, será
impedida a modificação da lotação enquanto não forem adicionados mais autocarros
pela empresa de aluguer.
Se uma atividade for apagada sem ser selecionada em qualquer reserva, as
marcações dos autocarros associadas são também eliminadas, desocupando essa data
para esse autocarro. Caso a atividade já tenha sido selecionada por alguns clientes ela
pode igualmente ser removida do sistema sem ter preenchido todas as vagas, não
interferindo nas restantes marcações.
2.1.4 Viagens
Definiu-se que uma viagem seria um destino nacional e a base da reserva que o
cliente irá efetuar. Relativamente à viagem considerou-se que a agência é um mero
mediador, uma vez que estes destinos são hotéis, resorts, pousadas e parques de
campismo distribuídos pelas cidades do país e no preço base apenas se inclui a estadia
14. Descrição Técnica
9
diária, não sendo a agência responsável pela forma como o cliente fará essa
deslocação.
As operações a realizar neste bloco serão:
Inserir uma nova viagem;
Listar todas as viagens no sistema;
Alterar uma viagem;
Apagar uma viagem.
A opção alterar viagem vai permitir mudar o preço diário da estadia, uma vez
que estes podem variar conforme as épocas do ano.
2.1.5 Reservas
Uma reserva será a marcação de uma viagem por um cliente, que pode ter
adicionado ou não um conjunto de atividades durante o período de tempo que dura
essa mesma viagem.
As operações a realizar neste bloco serão:
Inserir uma nova reserva;
Listar todas as reservas;
Consultar uma reserva;
Cancelar uma reserva;
Eliminar uma reserva.
Ao adicionar uma nova reserva, poderá ser selecionada a viagem pretendida,
bem como um conjunto de atividades se assim for desejado. O sistema estará
programado para dar avisos e impedir a introdução de atividades em quatro situações:
A data da atividade não estiver compreendida na data da viagem;
A localização geográfica da viagem não for a mesmo da atividade.
Se houver sobreposição de atividades;
Se a atividade já tiver sido inserida.
O sistema será desenhado para aceitar sobreposição de datas de atividade em
apenas uma situação: se uma das atividades necessitar autocarro e a outra não. Esta
situação está prevista para a contingência, por exemplo, de o cliente comprar a
15. Descrição Técnica
10
atividade “Ginásio” que lhe permite ir às instalações do ginásio desde as 8:00 as 22:00
e a meio do dia ter uma atividade envolvendo um autocarro.
A opção listar reservas dará uma vista abrangente de todas as reservas no
sistema, não especificando no entanto o teor das atividades, apenas a quantidade. Na
opção consultar reserva já se poderá ver individualmente cada reserva, bem como o
teor de cada atividade.
Caso um cliente pretenda e seja aceite pela agência, uma reserva pode ser
cancelada, e o saldo despendido restituído. Quando uma reserva é cancelada, a
mesma é retirada do histórico do cliente, e todos os valores são atualizados para repor
as vagas deixadas em branco.
A opção eliminar reserva, remove definitivamente a reserva deste bloco de
dados sem prejuízo de todas as marcações efetuadas. No entanto, existe uma situação
prevista: caso a reserva estivesse cancelada ela é simplesmente apagada, mas caso
contrário será adicionada ao histórico da agência e é o único dado que não pode ser
apagado, uma vez que recolhe informações desde o cliente, ao autocarro utilizado,
atividades e viagens.
Adicionalmente a este bloco será anexado na opção inserir, um pequeno extra
que permita ao utilizador caso deseje, atribuir um desconto entre 5 e 25% antes de
concluir a reserva.
2.1.6 Histórico
O histórico foi definido para salvar dados de clientes, autocarros e reservas. Estes
serão todos os dados que não aparecerão diretamente nos blocos anteriores, pois
estão dependentes da interligação de dados.
O histórico de clientes irá armazenar os dados de todas as reservas realizadas
por um determinado cliente, bem como mostrar o número total de viagens e saldo
despendido, e poderá ser consultado cliente a cliente.
O histórico de autocarros irá mostrar todos os horários ocupados na realização
de atividades, bem como o número de utilizações e o total de horas acumulado por
cada autocarro.
16. Descrição Técnica
11
O histórico de viagens irá mostrar todas as reservas apagadas do sistema
principal e é uma forma de salvaguardar os dados presentes na agência uma vez que
apresenta um leque variado de dados que vai desde o código da reserva, nome do
cliente, viagem realizada, número de atividades, datas e localização.
2.2 Construção das classes
Para desenvolver o modelo proposto, foi necessário criar uma série de classes
que o sustentasse. Algumas das variáveis de instância das classes são consequência
direta dos requisitos do trabalho, outras foram incluídas como melhoramento ou com
alguma função específica. Todas foram declaradas com o identificador private, o que
as tornam restritas à própria classe.
2.2.1 Classe Cliente
Os requisitos iniciais para esta classe eram o código de cliente, nome, morada e
histórico das viagens realizadas. Foram adicionadas as variáveis identificação,
telefone, dataAdesão, númeroViagens e acumuladoViagens.
private int código;
private string nome;
private string identificação;
private string morada;
private int telefone;
private DateTime dataAdesão;
private int númeroViagens;
private double acumuladoViagens;
private HashSet<Reserva> histórico;
O nome, identificação, morada, telefone e dataAdesão são dados a preencher
pelo utilizador aquando a inserção do cliente, uma vez que o código é gerado
automaticamente pelo sistema, iniciando-se em 1000 por defeito.
public Cliente(int c, string n, string i, string m, int t, DateTime d)
{
código = c;
nome = n;
identificação = i;
morada = m;
telefone = t;
dataAdesão = d;
númeroViagens = 0;
acumuladoViagens = 0;
histórico = new HashSet<Reserva>();
}
17. Descrição Técnica
12
Como se pode observar, o código é passado ao construtor da classe, no entanto
este é calculado automaticamente noutra estrutura. O númeroViagens e o
acumuladoViagens são iniciados a zero e representam respetivamente o número de
reservas efetuado por um cliente e o total pago em viagens. O histórico guarda os
dados das reservas efetuadas por cada cliente. Optou-se por uma coleção do tipo
HashSet e esta é apenas criada, uma vez que inicialmente não existem reservas para o
cliente.
2.2.2 Classe Autocarro
Os requisitos iniciais para esta classe eram um código e uma lotação.
private int código;
private string matrícula;
private int lotação;
private int totalHoras;
private HashSet<DateTime> ocupação;
private bool estado;
Foram adicionadas as variáveis matrícula, totalHoras, ocupação, e estado. A
matrícula foi adicionada apenas por uma questão de referência, não tendo qualquer
efeito prático, uma vez que tal como na Classe Cliente a geração do código aqui se
processa de forma automática e se inicia por defeito em 1000.
public Autocarro(int c, string m, int l)
{
código = c;
matrícula = m;
lotação = l;
totalHoras = 0;
ocupação = new HashSet<DateTime>();
estado = true;
}
O totalHoras foi adicionado e é reiniciado a zero quando a classe é criada com o
intuito de ser a variável de controlo responsável por retirar o autocarro de circulação
quando este atingir as 100 horas de utilização. Isto funciona simultaneamente com a
variável lógica estado que é iniciada a true. Um autocarro só poderá ser selecionado
para uma atividade se o seu estado lógico for true. Quando o totalHoras for maior ou
igual a 100 ele passa a false e torna-se indisponível.
A ocupação, guarda objetos da Classe DateTime, contendo as datas de início e
fim das atividades onde os autocarros participam e servirá para futuramente fazer as
18. Descrição Técnica
13
estatísticas do sistema. Optou-se por uma coleção do tipo HashSet e esta é apenas
criada, uma vez que inicialmente não existe qualquer data atribuída.
2.2.3 Classe Atividade
Os requisitos iniciais para esta classe eram um código, descrição, preço, número
de clientes inscritos e um conjunto de autocarros associados.
private string código;
private string descrição;
private double preço;
private int lotação;
private int contador;
private DateTime início;
private DateTime fim;
private string localização;
private bool transporte;
private HashSet<Autocarro> autocarros;
private bool estado;
private bool selected;
Para calcular o número de clientes inscritos, optou-se por atribuir uma lotação
inicial e incrementar um contador sempre que a atividade fosse selecionada, dando
assim pela diferença o número de vagas disponíveis em vez do número de inscritos.
Foram ainda adicionadas as variáveis início, fim, localização, transporte, estado
e selected. O início e o fim são variáveis do tipo DateTime e representam a hora de
início e fim da atividade, enquanto a localização indica a zona geográfica onde ela vai
ocorrer.
Para esta classe foram definidos dois construtores, uma vez que existem duas
situações possíveis:
A atividade necessita de autocarros e recebe um HashSet com os
autocarros disponibilizados para essa atividade.
public Atividade(string c, string d, double p, int l, DateTime i,
DateTime f, string loc, bool t, HashSet<Autocarro> a)
{
código = c;
descrição = d;
preço = p;
lotação = l;
contador = 0;
início = i;
fim = f;
localização = loc;
transporte = t;
autocarros = a;
estado = true;
selected = false; }
19. Descrição Técnica
14
A atividade não necessita de autocarros e o HashSet é apenas iniciado.
public Atividade(string c, string d, double p, int l, DateTime i,
DateTime f, string loc, bool t)
{
código = c;
descrição = d;
preço = p;
lotação = l;
contador = 0;
início = i;
fim = f;
localização = loc;
transporte = t;
autocarros = new HashSet<Autocarro>();
estado = true;
selected = false;
}
Existem três variáveis do tipo lógico que servem de apoio ao sistema nesta
classe: transporte, estado e selected. O transporte indica se a atividade necessita
(true) ou não (false) de transporta e é passada pelo sistema. Esta indicação torna-se
necessária para outras instruções.
Um pouco mais complexa é a utilização das variáveis estado e selected. Quando
o contador da classe for igual à lotação significa que não há mais vagas disponíveis.
Assim, o estado que inicialmente é true, passa a false e a atividade deixa de estar
disponível para seleção por parte dos clientes.
A variável selected é uma variável de controlo que permite verificar se algum
cliente já escolheu a atividade. A razão deste controlo é caso a atividade seja apagada
pelo utilizador, é necessário salvaguardar que se mantem a marcação do autocarro.
Assim, após a primeira seleção da atividade por um cliente, o estado lógico passa de
false para true e caso a atividade seja apagada as marcações são mantidas. Caso o
estado lógico se mantenha em false, significa que nenhum cliente selecionou a
atividade e a marcação do autocarro é posteriormente cancelada.
2.2.4 Classe Viagem
Os requisitos iniciais para esta classe eram um código, descrição, preço base e
um programa contendo um conjunto de atividades. Uma vez que esta solução tem um
desenho diferente e inclui o conjunto de atividades aquando a marcação da reserva,
eliminou-se essa componente e modificou-se o preço base para o preçoDia da estadia.
Adicionalmente inseriu-se a variável localização que indica o destino da viagem.
20. Descrição Técnica
15
private int código;
private string descrição;
private double preçoDia;
private string localização;
A Classe Viagem é uma das classes mais simples, possuindo apenas como
automatismo a geração de código automático que como as anteriores por defeito
inicia em 1000.
public Viagem(int c, string d, double p, string l)
{
código = c;
descrição = d;
preçoDia = p;
localização = l;
}
2.2.5 Classe Reserva
Para esta classe não existiam critérios pré-definidos, assim, optou-se por definir
um código, um titular, um destino, um conjuntoAtividades, um início, um fim, um
preçoFinal e um estado.
private int código;
private Cliente titular;
private Viagem destino;
private HashSet<Atividade> conjuntoAtividades;
private DateTime início;
private DateTime fim;
private double preçoFinal;
private bool estado;
O código será gerado automaticamente começando por defeito em 1000. O
titular será um objeto pertencente à Classe Cliente e o destino um objeto pertencente
à Classe Viagem. O início e o fim serão dois objetos pertencentes à Classe DateTime e
representam as datas de início e fim de viagem.
Uma vez que nem todas as reservas teriam atividades selecionadas, optou-se
pelo uso de dois construtores:
public Reserva(int c, Cliente t, Viagem d, HashSet<Atividade> conj,
DateTime i, DateTime f, double p)
{
código = c;
titular = t;
destino = d;
conjuntoAtividades = conj;
início = i;
fim = f;
preçoFinal = p;
estado = true;
}
21. Descrição Técnica
16
Quando são selecionadas atividades na reserva, é passado um HashSet com esse
conjunto de atividades. Quando não existem atividades selecionadas, o HashSet é
apenas iniciado.
public Reserva(int c, Cliente t, Viagem d,
DateTime i, DateTime f, double p)
{
código = c;
titular = t;
destino = d;
conjuntoAtividades = new HashSet<Atividade>();
início = i;
fim = f;
preçoFinal = p;
estado = true;
}
A variável lógica estado é iniciada a true, e vai indicar se a reserva está ou não
validada. Esta seleção foi adicionada para permitir o cancelamento de reservas noutras
operações, através da passagem de estado para false.
O preçoFinal vai ser calculado internamente e passado ao construtor baseando-
se na diferença entre o dia final e dia inicial da reserva, multiplicando pelo preço diário
da viagem e somando os preços das várias atividades.
2.2.6 Classe Agência
Esta classe não consta no diagrama de blocos do sistema, no entanto, foi criada
pois é a classe que armazena todos os dados do sistema.
private string nome;
private string localização;
private List<Cliente> clientes;
private List<Autocarro> autocarros;
private List<Atividade> atividades;
private List<Viagem> viagens;
private HashSet<Reserva> reservas;
private HashSet<Reserva> históricoApagadas;
Para o problema em questão apenas estão ser a geridos os dados de uma
agência, por isso não existem menus associados a esta classe, mas se fosse necessário
gerir todas as sucursais de uma agência mãe já seria necessário criar outro tipo de
estruturas.
A variável nome e localização são referentes ao nome e morada da agência, que
no trabalho foram referenciados como Viagens EEC, Barcelos.
22. Descrição Técnica
17
public Agência(string n, string l)
{
nome = n;
localização = l;
clientes = new List<Cliente>();
autocarros = new List<Autocarro>();
atividades = new List<Atividade>();
viagens = new List<Viagem>();
reservas = new HashSet<Reserva>();
históricoApagadas = new HashSet<Reserva>();
}
Para o armazenamento de dados de sistema optou-se pela utilização de coleções
do tipo List e para armazenar dados gerados pelo sistema coleções do tipo HashSet
pois aqui ir-se-á trabalhar com conjuntos sem repetições.
Assim, as variáveis clientes, autocarros, atividades e viagens foram definidas
como List e as variáveis reservas e históricoApagadas definidas como HashSet.
2.2.7 Classe Program
A Classe Program, por onde a aplicação se inicia, funciona como o motor de todo
o sistema. Aqui foi criado um objeto da Classe Agência que permite o armazenamento
de todos os dados do sistema. Adicionalmente foram criados dois métodos que
permitem a gravação e leitura dos dados em ficheiro: Serialize e Deserialize.
static class Program
{
public static Agência agência = new Agência("Viagens EEC", "Barcelos");
O método Serialize permite a gravação de todos os dados presentes no sistema
em ficheiro. Para isso foi necessário acrescentar em todas as classes que continham
dados graváveis o comando [Serializable] na sua definição.
private const string SERIALIZATION_NAME = "dados.dat";
public static void Serialize()
{
FileStream fs = new FileStream(SERIALIZATION_NAME, FileMode.Create);
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs, agência);
fs.Close();
}
O método Deserialize permite a leitura e carregamento dos dados do ficheiro
para o sistema. Caso o ficheiro não exista, uma mensagem é impressa com a
mensagem: Base de dados vazia!
23. Descrição Técnica
18
public static void Deserialize()
{
try
{
FileStream fs = new FileStream(SERIALIZATION_NAME, FileMode.Open);
BinaryFormatter bf = new BinaryFormatter();
agência = (Agência)bf.Deserialize(fs);
fs.Close();
}
catch
{
MessageBox.Show("Base de dados vazia!");
}
}
2.3 Implementação dos interfaces gráficos
Para desenvolver a componente gráfica do trabalho, foi necessário criar uma
série de Windows Forms, uma por cada menu de navegação.
As Windows Forms são construídas utilizando classes pertencentes à biblioteca
System.Windows.Forms (ToolBox).
Ao todo foram utilizadas nove tipos diferentes de classes pertencentes à
biblioteca System.Windows.Forms, com diferentes finalidades.
2.3.1 MenuStrip
Permite efetuar múltiplas seleções dentro do mesmo menu. Foram utilizados
dois MenuStrip para criar o menu principal, um para as funções de introdução de
dados, outro para as funções de efetuar reservas, calcular estatísticas e consultar
históricos.
Figura 2 – MenuStrip.
24. Descrição Técnica
19
2.3.2 Label
Permite adicionar texto à Windows Form que não pode ser alterado. Está
constantemente presente para fornecer indicações ao utilizador.
Figura 3 – Label.
2.3.3 Button
Permite despoletar um evento, efetuar seleções ou ativar instruções. Os Button
são largamente utilizados ao longo do trabalho quer para ativar instruções como para
navegar para outros menus.
Figura 4 – Button.
2.3.4 TextBox
Permite escrever dados para serem lidos pelo sistema ou receber dados através
do sistema. A escolha na TextBox recaiu aquando da necessidade de introduzir dados
para o sistema (clientes, autocarros, atividades e viagens) ou na introdução de
pequenas quantidades de informação. A nível de receção de informação, foi utilizada,
sempre que a reduzida quantidade de informação não justificasse uma DataGridView.
Figura 5 – TextBox.
25. Descrição Técnica
20
2.3.5 DataGridView
É uma tabela que permite ler e escrever informação, sendo que o número de
colunas pode ser configurado conforme as necessidades. As DataGridView apenas
foram utilizadas em modo de leitura (sendo protegido o seu modo de acesso à escrita)
sempre que grandes quantidades de informação a apresentar o justificaram.
Figura 6 – DataGridView.
2.3.6 ComboBox
Permite mostrar o conteúdo presente numa coleção, ou então uma sequência de
strings previamente inseridas. As ComboBox são largamente utilizadas para fazer a
seleção de clientes, autocarros, atividades e viagens ao longo da aplicação.
Figura 7 – ComboBox.
2.3.7 DateTimePicker
Permite selecionar uma data e uma hora através de um calendário. Os
DateTimePicker foram utilizados com duas funções: recolher dias e horas.
Figura 8 – DateTimePicker.
26. Descrição Técnica
21
2.3.8 RadioButton
Funciona tipo escolha múltipla, permitindo a escolha de apenas uma das opções
caso seja selecionado. Foi utilizado apenas uma vez, para selecionar se as atividades
necessitam ou não de transporte.
Figura 9 – RadioButton.
2.3.9 PictureBox
Permite adicionar uma imagem como pano de fundo ou anexar uma imagem a
uma Windows Form. Foram utilizadas várias PictureBox ao longo do trabalho para
realçar o carater informativo da aplicação em questão e na secção about us para
identificar visualmente os executantes do trabalho.
Figura 10 – PictureBox.
2.4 Algoritmos desenvolvidos
Para que o sistema funcionasse corretamente e correspondesse às exigências
pretendidas foi necessário desenvolver uma série de programação em todas as classes
geradas.
Adicionalmente e de forma a manter o sistema o mais autónomo possível, foram
criados uma série de algoritmos para gestão do sistema.
27. Descrição Técnica
22
2.4.1 Propriedades
Em cada classe foram adicionadas uma série de propriedades para acesso às
variáveis de instância e quando necessário, alteração do valor das mesmas.
public int NúmeroViagens
{
get { return númeroViagens; }
set { númeroViagens = value; }
}
Esta propriedade permite através do comando get, ter acesso ao conteúdo da
variável númeroViagens presente na Classe Cliente. O comando set permite alterar o
valor presente nessa variável, sendo deste modo que se processam as alterações dos
dados no sistema.
Este exemplo de propriedade é útil para demonstrar como se realiza o processo
de atualização do número de viagens de um dado cliente. Sempre que ele efetua uma
reserva, através do comando set o número de viagens é incrementado numa unidade.
Caso a reserva seja cancelada o número de viagens é decrementado pelo mesmo
processo. Quando se pretende mostrar ao utilizador o número de viagens realizado
por um determinado cliente, é o comando get que retorna o valor do conteúdo
presente nessa mesma variável.
2.4.2 Métodos de instância
Em certas classes surgiu a necessidade de desenvolver métodos de instância para
efetuar algum teste ou retornar um objeto pertencente a uma coleção.
public bool verificarTempoFuncionamentoAutocarro(Autocarro a)
{
if (a.TotalHoras < 100)
return (true);
else
return (false);
}
Este método, quando invocado, permite verificar se o total de horas de
funcionamento do autocarro selecionado para a atividade excede as 100 horas. Caso
se verifique, o método vai retornar o estado lógico true para o sistema poder invalidar
o autocarro, deixando este de estar selecionável na escolha de atividades. Este
exemplo de código representa um dos vários algoritmos de controlo presentes ao
longo do programa, desenvolvido especificamente a partir de uma classe.
28. Descrição Técnica
23
2.4.3 Geração automática de códigos
Como já foi sendo referido, o sistema, atribui automaticamente os códigos para
os clientes, autocarros, atividades e reservas. Nos quatro casos o processo é idêntico,
sendo que em seguida se demonstra a forma realizada para os clientes.
if (Program.agência.Clientes.Count() == 0)
código = 1000;
else
{
Cliente c1 = Program.agência.Clientes.Last();
código = c1.Código + 1;
}
Se a coleção de clientes estiver vazia, o sistema atribui ao cliente o número 1000.
Senão, o sistema vai buscar o último objeto introduzido na coleção, retira o seu código
e incrementa uma unidade.
2.4.4 Verificação do código da atividade
Uma vez que um dos critérios definidos para as atividades seria que o código
devia ser alfanumérico e único, não se aplicou o gerador automático de códigos. Podia-
se ter implementado um algoritmo que gerasse carateres alfanuméricos aleatórios, no
entanto, tal situação não traria qualquer vantagem uma vez que a primeira letra
introduzida por norma é a sigla da localidade da atividade ou alguma referência à
mesma. Assim, implementou-se um algoritmo que testasse se o código introduzido já
existia no sistema e produzisse um aviso em caso afirmativo.
string código = textBox1.Text;
bool estado = Program.agência.verificarCódigoAtividade(código);
if (estado == true)
MessageBox.Show("Código inválido!");
else
{
Adicionalmente na Windows Form criou-se um botão que o utilizador pode
utilizar para validar o código antes de carregar a atividade. Assim, pode garantir a
validade do código antes de tentar a inserção da atividade.
O algoritmo responsável por validar o estado do código introduzido é um
método de instância desenvolvido na Classe Agência.
29. Descrição Técnica
24
public bool verificarCódigoAtividade(string n)
{
if (n == "")
return (true);
else
{
foreach (Atividade a in Atividades)
if (a.Código == n)
return (true);
}
return (false);
}
O método recebe uma string que representa o código da atividade a testar e vai
percorrer todas as atividades presentes na coleção, comparando os códigos presentes
na coleção com o código recebido. Se encontrar uma correspondência devolve true.
Caso a string introduzida esteja vazia, também devolve true, uma vez que esta é a
definição para um código inválido.
Sempre que o estado for true no algoritmo de verificação, o sistema gera um
aviso de “Código inválido!” e caso o utilizador tente inserir a atividade o sistema não o
permitirá.
2.4.5 Cálculo da diferença entre dias
Quando se insere uma nova reserva no sistema, o utilizador só vai introduzir a
data de início da viagem e a data final. Assim, o preço final da viagem que é o preço
diário multiplicado pelo número de dias terá de ser calculado pelo sistema.
public int diferençaDatas(int m1, int m2, int d1, int d2)
{
if ((m1 > m2) || (m2 - m1 > 1))
return (-1);
else if ((m1 == m2) && (d1 == d2))
return (0);
else if ((m1 == m2) && (d1 < d2))
return (d2 - d1);
else if ((m1 < m2) && (m1 % 2 != 0))
return (d2 - d1 + 31);
else if ((m1 < m2) && (m1 % 2 == 0) && (m1 != 2))
return (d2 - d1 + 30);
else if ((m1 < m2) && (m1 == 2))
return (d2 - d1 + 28);
return (-1);
}
Surgiu assim a necessidade de implementar um algoritmo que calculasse esse
número de dias, tendo em consideração todas os fatores como a diferença entre
meses e o fato de Fevereiro apenas ter 28 dias.
30. Descrição Técnica
25
Em seguida o número de dias retornado é multiplicado pelo preço diário,
obtendo-se o preço da viagem ao que ainda o sistema soma o valor das atividades caso
sejam selecionadas.
2.4.6 Automatismos e mecanismos de controlo
Foram desenvolvidos outros algoritmos que devido à sua complexidade e por o
seu código se encontrar compartilhado entre várias classes do sistema se torna difícil
explicar, mas que podem ser consultados no código fonte da aplicação. Destacam-se:
Marcação automática dos autocarros aquando da criação de uma atividade
envolvendo autocarros;
Cancelamento automático das marcações dos autocarros aquando da
eliminação de uma atividade envolvendo um ou mais autocarros;
Ajuste automático do número de autocarros aquando da alteração da
lotação de uma atividade envolvendo um autocarro;
O cancelamento de uma reserva por um cliente repõe o número de vagas
deixado em vazio automaticamente numa atividade.
A nível de interface foi igualmente desenvolvida toda uma série de programação
de modo a prevenir bugs no sistema e evitar falhas na introdução de dados por
utilizadores inexperientes.
2.5 Outros trabalhos
Da forma como a solução foi idealizada, recorrendo a soluções automatizadas, o
trabalho estaria concluído. No entanto faltava responder aos objetivos 6 a 10 do
problema, que apenas fariam sentido se o sistema fosse de introdução manual.
Figura 11 – Menu “Estatísticas”.
31. Descrição Técnica
26
Assim, criou-se uma secção individual dentro da aplicação denominada
“Estatísticas” para responder individualmente a cada um desses objetivos.
Todas as operações efetuadas no menu Estatísticas são de mera consulta, uma
vez que se trata apenas de uma simulação, que seria o caso de o sistema ser manual.
Adicionalmente ainda foi criada a secção “Informações do Sistema” que dá o número
de dados presentes no sistema (clientes, autocarros, atividades, viagens, reservas) e
ainda indica os nomes do cliente com maior número de viagens efetuadas e maior
dinheiro gasto em viagens.
Figura 12 – Menu “Informações”.
Finalmente foi adicionado um pequeno menu com as informações relativas à
instituição de ensino e o executante do trabalho.
Figura 13 – Menu “About Us”.
32. 27
3 Testes e Resultados
Para efetuar os testes à aplicação, utilizou-se a mesma com o ficheiro de dados
previamente carregado. Atualmente o sistema possui 4 clientes, 10 autocarros e
atividades/viagens marcadas para a zona de Braga e Viana do Castelo.
Inicialmente será introduzido um novo cliente.
Figura 14 – Inserção de um novo cliente.
Existiam 4 clientes inseridos previamente, assim fazendo uma rápida listagem à
base de dados de clientes pode-se verificar que o sistema terá atribuído
automaticamente o número 1004 ao Carlos e o seu número de viagens compradas,
assim como o saldo gasto estará a zero.
Figura 15 – Listar todos os clientes.
33. Testes e Resultados
28
Não é necessário adicionar qualquer autocarro de momento, mas pode-se fazer
uma listagem ao sistema para verificar o ponto da situação.
Figura 16 – Listar todos os autocarros.
É possível verificar que todos os autocarros estão ativos, uma vez que nenhum
deles tem um total de horas maior ou igual a 100 horas. Em seguida vai-se verificar as
atividades existentes no sistema.
Figura 17 – Listar todas as atividades.
Quando uma atividade necessita de um ou mais autocarros, as suas matrículas
aparecem na coluna “Transporte”. Os horários de ocupação de cada autocarro podem
ainda ser consultados no histórico de autocarros.
34. Testes e Resultados
29
Antes de se avançar para a marcação de uma reserva, será confirmado que
segundo a figura 17, o autocarro 95-71-PH encontra-se escalado para uma atividade no
dia 01/01/2014 das 10 às 12:00 e no dia 02/01/2014 das 10 às 12:00.
Figura 18 – Horários de utilização.
Como se pode verificar, o histórico dos autocarros que neste caso são os horários
de utilização, além de dar todos os períodos em que o autocarro se encontra
indisponível em alguma atividade, ainda indica o número de atividades em que
participa, bem como o número de horas de utilização.
Passando a efetuar uma reserva, ir-se-á utilizar o período de 1 a 2 de Janeiro de
2014, o que perfaz dois dias num destino em Viana do Castelo.
Figura 19 – Inserção de uma reserva.
35. Testes e Resultados
30
O Carlos, selecionou uma pousada a 60 euros por dia, durante dois dias o que
perfaz 120 euros. Adicionalmente selecionou três atividades no total de 40 euros
perfazendo um total de 160 euros. No final o utilizador aplicou-lhe um desconto de 5%
(opcional) que reduziu o preço do pacote para 152 euros como se vai verificar em
seguida no seu histórico. Note-se que o sistema permitiu a introdução de atividades
com horários sobrepostos uma vez que ambas não implicavam a utilização de
transporte. Uma delas era uma entrada no ginásio que o Carlos poderia realizar a
qualquer hora do dia. Em seguida já é possível consultar o histórico de cliente.
Figura 20 – Histórico Clientes.
A tabela “Viagens” dá a descrição de todas as viagens efetuadas por um cliente.
Na coluna “Atividades” aparece os códigos das atividades selecionados pelos clientes
em cada viagem que podem depois ser consultados na tabela “Atividades” que se
encontra imediatamente abaixo.
Como foi possível observar na figura 15, o cliente 1000, Paulo, possuía uma
reserva efetuada no valor de 218,50 euros. À última da hora ele teve de cancelar, o
que foi aceite pela agência de viagens.
Figura 21 – Cancelar Reserva.
36. Testes e Resultados
31
Se o histórico deste cliente for agora consultado, ele deixa de ter qualquer dado
para apresentar, uma vez que os dados associados a esta reserva foram atualizados e
as marcações canceladas.
Figura 22 – Histórico do cliente Paulo.
37. 32
4 Conclusões
O desenvolvimento deste trabalho foi aliciante, na medida em que foram
abordadas novas áreas tais como o desenvolvimento de interfaces gráficos, o que
originou uma maior necessidade de pesquisa para atingir as soluções desejadas.
A nível pessoal, foi altamente satisfatório, aplicar os conhecimentos adquiridos
ao longo de toda uma formação no campo da programação para produzir uma
aplicação de alta complexidade e com o grau de exigência que era pedido.
O modelo implementado foi ligeiramente modificado de forma a melhorar a
qualidade final da aplicação, mas no entanto isso também conduziu a alguma
dificuldade em enquadrar alguns dos objetivos iniciais em determinado ponto, uma
vez que estes não se contextualizavam no desenvolvimento obtido.
Por esse motivo surgiu o menu “Estatísticas” que foi a resposta aos objetivos que
não se enquadravam no modelo desenvolvido. Este menu “Estatísticas” torna-se
irrelevante para o funcionamento do sistema e não teria sido aplicado se não se
tratasse de um projeto académico.
Todos os objetivos propostos inicialmente foram realizados com sucesso e ainda
se criaram uma série de estruturas que foram além das exigências iniciais. O simples
fato de o sistema ser praticamente automático, retira o poder de decisão das mãos do
utilizador final evitando erros inerentes a este processo. Foram adicionadas estruturas
importantes como o cancelar uma reserva ou efetuar um desconto automático,
instruções que se fossem efetuadas manualmente seriam morosas e altamente
sujeitas a erro.
A principal limitação do trabalho, será não ter uma base de dados associada para
posterior exportação dos dados. Assim, surge como trabalho futuro a construção de
uma base de dados em SQL e algumas melhorias a nível gráfico.
Concluindo, pode-se afirmar que foi desenvolvida uma aplicação com um bom
desempenho que poderia perfeitamente ser aplicada a nível comercial, contendo
algoritmos na sua programação de elevada complexidade o que valoriza todo o
trabalho desenvolvido.
38. 33
5 Referências Bibliográficas
[1] António Tavares, Eva Oliveira, João Carlos, Luís Ferreira, Manuel Cunha, Marco
Costa, “C# Essencial”, IPCA, 2007-2009.
[2] Carlos Vamberto, “Curso de C#”.
[3] Rob Miles, “C# Programming – Department of Computer Science University of
Hull”, August 2012.