Autor Tópico: Aula 8 - Aplicação contextualizada  (Lida 2641 vezes)

0 Membros e 1 Visitante estão vendo este tópico.

Offline Jefferson

  • Zelador
  • Hero Member
  • *****
  • Mensagens: 1854
  • Aprovação: +0/-0
    • Ver Perfil
    • http://ryan.com.br
Aula 8 - Aplicação contextualizada
« Online: Abril 25, 2019, 01:37:04 pm »
Citar
A Imobiliária Pirâmide deseja emitir fatura para pagamento de aluguéis dos imóveis locados. A imobiliária pode inserir e remover imóveis (um por um) que possuem: código_imóvel, código_cliente (código_cliente, nome, struct endereço e cpf), valor_aluguel, IPTU e situação. (TAD's - Cliente e Imóveis) O valor da fatura é: fatura = valor_aluguel + IPTU + tx_administracao + tx_banco

Taxas de administração (percentual do valor do aluguel)
Aluguel de até R$500: 8%
Aluguel entre R$500 e R$2000: 5%
Aluguel acima de R$2000: 3%

Taxa do banco
Aluguel de até R$1000: R$1,50
Aluguel acima de R$1000: R$0,95

As taxas de administração e do banco utilizam-se das tabelas, respectivamente. O sistema deve calcular e emitir as faturas sendo que, se a situação for igual a <<atraso>>, escrever também uma mensagem convidando o cliente a comparecer ao escritório da imobiliária. OBS: um cliente pode ter mais de um imóvel.

Menu:
  • Inserir um novo Imóvel/Cliente
  • Remover um Imóvel pelo Código
  • Alterar um Imóvel pelo Código
  • Calcular o Valor da Fatura de um Imóvel apresentando a situação.
  • Imprimir todos os Clientes/Imóveis

Eu incluí o projeto inteiro (Dev-C++) em um zip anexo, para facilitar.
Meu programa requer dois arquivos: clientes.txt e imoveis.txt que não estão exibidos aqui, mas estão no zip em anexo. Notar que todos os dados pessoais em clientes.txt são fictícios, obtidos em um gerador online.

main.cpp

Código: C++
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
#include <iostream>#include <strings.h>#include <sstream>#include <locale>#include <fstream>#include "imovel.h"#include "cliente.h" using std::cout;using std::cin;using std::string;using std::stringstream; bool arquivoExiste(const char *arquivo);int receberValor(string texto);void emitirFatura (Timovel *imovel, int numRec, Tcliente *cliente);int main() {     setlocale(LC_ALL,"");        //==================================================================================    Timovel * ptrImoveis= imovel_criar();     int numImoveis=0;     if (arquivoExiste("imoveis.txt")){        //Eu uso fstream e não ifstream porque pretendo usar o mesmo arquivo como saída de dados        std::fstream arqImoveis("imoveis.txt");         string linha="";        getline(arqImoveis, linha);        //A primeira linha do arquivo contém o número de registros armazenados nele        int numImoveisArq=stoi(linha);         //Leio o registros com os clientes a partir do arquivo e adiciono ao array        for (int i=0;i<numImoveisArq;i++){            imovel_adicionar(ptrImoveis,&numImoveis, &arqImoveis);        }    }     //==================================================================================    Tcliente * ptrClientes= cliente_criar();     int numClientes=0;        if (arquivoExiste("clientes.txt")){        //Eu uso fstream e não ifstream porque pretendo usar o mesmo arquivo como saída de dados        std::fstream arqClientes("clientes.txt");         string linha="";        getline(arqClientes, linha);        //A primeira linha do arquivo contém o número de registros armazenados nele        int numClientesArq=stoi(linha);         //Leio o registros com os clientes a partir do arquivo e adiciono ao array        for (int i=0;i<numClientesArq;i++){            cliente_adicionar(ptrClientes,&numClientes, &arqClientes);        }    }    //==================================================================================        string opcao="";     while (opcao!="0"){         cout <<"Número de clientes cadastrados: " << numClientes << '\n';        cout <<"Número de imóveis cadastrados: " << numImoveis << "\n\n";        cout <<"Escolha uma opção e em seguida tecle [ENTER]:\n\n";         cout <<"1 - Adicionar um imovel.\n";        if (numImoveis>0) cout <<"2 - Listar todos os imoveis.\n";        if (numImoveis>0) cout <<"3 - Deletar imovel.\n";        if (numImoveis>0) cout <<"4 - Editar imovel.\n";        if (numImoveis>0) cout <<"5 - Emitir Fatura.\n";        cout <<"6 - Adicionar um cliente.\n";        if (numClientes>0) cout <<"7 - Listar todos os clientes.\n";        cout <<"0 - Sair do programa.\n";                getline(cin, opcao);        if (opcao=="1"){            if (system("CLS")) system("clear");            imovel_adicionar(ptrImoveis,&numImoveis);            cout << "imovel adicionado.";            cout << "Tecle ENTER para voltar ao menu.";        };         if (opcao=="2"){            imovel_imprimirTodos(ptrImoveis, numImoveis);            cout << "tecle ENTER para voltar ao menu.";            getline(cin, opcao);        };         if (opcao=="3"){            if (system("CLS")) system("clear");            imovel_deletar(ptrImoveis, &numImoveis, receberValor("Digite o número do imovel a deletar: "));            cout << "imovel deletado. ";            cout << "Tecle ENTER para voltar ao menu.";            getline(cin, opcao);        };                if (opcao=="4"){            if (system("CLS")) system("clear");            imovel_editar(ptrImoveis,  receberValor("Digite o número do imovel a editar: ")-1);            cout << "imovel editado. ";            cout << "Tecle ENTER para voltar ao menu.";            getline(cin, opcao);        };                if (opcao=="5"){            if (system("CLS")) system("clear");            emitirFatura(ptrImoveis,  receberValor("Digite o número do imovel a faturar: ")-1, ptrClientes);            cout << "imovel faturado. ";            cout << "Tecle ENTER para voltar ao menu.";            getline(cin, opcao);        };                if (opcao=="6"){            if (system("CLS")) system("clear");            cliente_adicionar(ptrClientes,&numClientes);            cout << "cliente adicionado. ";            cout << "Tecle ENTER para voltar ao menu.";            getline(cin, opcao);        };         if (opcao=="7"){            cliente_imprimirTodos(ptrClientes, numClientes);            cout << "Tecle ENTER para voltar ao menu.";            getline(cin, opcao);        };      if (system("CLS")) system("clear");     }         // se eu tentar sair do programa sem ter adicionado nenhum item o programa trava    if (numImoveis>0) imovel_destruir(ptrImoveis);    if (numClientes>0) cliente_destruir(ptrClientes);return 0;} int receberValor(string texto){    string temp="";    int num=0;    while (true){        cout <<  texto;        getline(cin, temp);        stringstream myStream(temp);        if (myStream >>num) break; //sucesso na conversão            else            cout << "\nNúmero inválido. Tente de novo." << '\n';    };   return num;} bool arquivoExiste(const char *arquivo){    //Não é preciso fechar o stream porque o destrutor de ifstream é chamado    //na saída da função    std::ifstream infile(arquivo);    return infile.good();} void emitirFatura (Timovel *imovel, int numRec, Tcliente *cliente){        string codCliente= "";    string situacaoImovel= "";     float valorFatura= imovel_calcularFatura(imovel, numRec, &codCliente, &situacaoImovel);        //codCliente e situacaoCliente voltam de imovel_calcularFatura preenchido    cliente_imprimir( cliente, stoi(codCliente)-1);    cout << "Valor a pagar: R$" << valorFatura <<"\n";    if (situacaoImovel=="atrasado"){        cout<< "\n\nCaro cliente. Nosso sistema indica um débito em atraso.\n";        cout<< "Por favor entre am contato com nossa Central de Atendimento\n";        cout<< "para regularizar sua situação. Se esse débito já foi pago,\n";        cout<< "favor desconsiderar este aviso.\n\n";            }}

imovel.h

Código: C++
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
#include <iostream>#include <strings.h>#include <sstream>#include <locale>#include <fstream>#include "imovel.h"#include "cliente.h" using std::cout;using std::cin;using std::string;using std::stringstream; bool arquivoExiste(const char *arquivo);int receberValor(string texto);void emitirFatura (Timovel *imovel, int numRec, Tcliente *cliente);int main() {     setlocale(LC_ALL,"");        //==================================================================================    Timovel * ptrImoveis= imovel_criar();     int numImoveis=0;     if (arquivoExiste("imoveis.txt")){        //Eu uso fstream e não ifstream porque pretendo usar o mesmo arquivo como saída de dados        std::fstream arqImoveis("imoveis.txt");         string linha="";        getline(arqImoveis, linha);        //A primeira linha do arquivo contém o número de registros armazenados nele        int numImoveisArq=stoi(linha);         //Leio o registros com os clientes a partir do arquivo e adiciono ao array        for (int i=0;i<numImoveisArq;i++){            imovel_adicionar(ptrImoveis,&numImoveis, &arqImoveis);        }    }     //==================================================================================    Tcliente * ptrClientes= cliente_criar();     int numClientes=0;        if (arquivoExiste("clientes.txt")){        //Eu uso fstream e não ifstream porque pretendo usar o mesmo arquivo como saída de dados        std::fstream arqClientes("clientes.txt");         string linha="";        getline(arqClientes, linha);        //A primeira linha do arquivo contém o número de registros armazenados nele        int numClientesArq=stoi(linha);         //Leio o registros com os clientes a partir do arquivo e adiciono ao array        for (int i=0;i<numClientesArq;i++){            cliente_adicionar(ptrClientes,&numClientes, &arqClientes);        }    }    //==================================================================================        string opcao="";     while (opcao!="0"){         cout <<"Número de clientes cadastrados: " << numClientes << '\n';        cout <<"Número de imóveis cadastrados: " << numImoveis << "\n\n";        cout <<"Escolha uma opção e em seguida tecle [ENTER]:\n\n";         cout <<"1 - Adicionar um imovel.\n";        if (numImoveis>0) cout <<"2 - Listar todos os imoveis.\n";        if (numImoveis>0) cout <<"3 - Deletar imovel.\n";        if (numImoveis>0) cout <<"4 - Editar imovel.\n";        if (numImoveis>0) cout <<"5 - Emitir Fatura.\n";        cout <<"6 - Adicionar um cliente.\n";        if (numClientes>0) cout <<"7 - Listar todos os clientes.\n";        cout <<"0 - Sair do programa.\n";                getline(cin, opcao);        if (opcao=="1"){            if (system("CLS")) system("clear");            imovel_adicionar(ptrImoveis,&numImoveis);            cout << "imovel adicionado.";            cout << "Tecle ENTER para voltar ao menu.";        };         if (opcao=="2"){            imovel_imprimirTodos(ptrImoveis, numImoveis);            cout << "tecle ENTER para voltar ao menu.";            getline(cin, opcao);        };         if (opcao=="3"){            if (system("CLS")) system("clear");            imovel_deletar(ptrImoveis, &numImoveis, receberValor("Digite o número do imovel a deletar: "));            cout << "imovel deletado. ";            cout << "Tecle ENTER para voltar ao menu.";            getline(cin, opcao);        };                if (opcao=="4"){            if (system("CLS")) system("clear");            imovel_editar(ptrImoveis,  receberValor("Digite o número do imovel a editar: ")-1);            cout << "imovel editado. ";            cout << "Tecle ENTER para voltar ao menu.";            getline(cin, opcao);        };                if (opcao=="5"){            if (system("CLS")) system("clear");            emitirFatura(ptrImoveis,  receberValor("Digite o número do imovel a faturar: ")-1, ptrClientes);            cout << "imovel faturado. ";            cout << "Tecle ENTER para voltar ao menu.";            getline(cin, opcao);        };                if (opcao=="6"){            if (system("CLS")) system("clear");            cliente_adicionar(ptrClientes,&numClientes);            cout << "cliente adicionado. ";            cout << "Tecle ENTER para voltar ao menu.";            getline(cin, opcao);        };         if (opcao=="7"){            cliente_imprimirTodos(ptrClientes, numClientes);            cout << "Tecle ENTER para voltar ao menu.";            getline(cin, opcao);        };      if (system("CLS")) system("clear");     }         // se eu tentar sair do programa sem ter adicionado nenhum item o programa trava    if (numImoveis>0) imovel_destruir(ptrImoveis);    if (numClientes>0) cliente_destruir(ptrClientes);return 0;} int receberValor(string texto){    string temp="";    int num=0;    while (true){        cout <<  texto;        getline(cin, temp);        stringstream myStream(temp);        if (myStream >>num) break; //sucesso na conversão            else            cout << "\nNúmero inválido. Tente de novo." << '\n';    };   return num;} bool arquivoExiste(const char *arquivo){    //Não é preciso fechar o stream porque o destrutor de ifstream é chamado    //na saída da função    std::ifstream infile(arquivo);    return infile.good();} void emitirFatura (Timovel *imovel, int numRec, Tcliente *cliente){        string codCliente= "";    string situacaoImovel= "";     float valorFatura= imovel_calcularFatura(imovel, numRec, &codCliente, &situacaoImovel);        //codCliente e situacaoCliente voltam de imovel_calcularFatura preenchido    cliente_imprimir( cliente, stoi(codCliente)-1);    cout << "Valor a pagar: R$" << valorFatura <<"\n";    if (situacaoImovel=="atrasado"){        cout<< "\n\nCaro cliente. Nosso sistema indica um débito em atraso.\n";        cout<< "Por favor entre am contato com nossa Central de Atendimento\n";        cout<< "para regularizar sua situação. Se esse débito já foi pago,\n";        cout<< "favor desconsiderar este aviso.\n\n";            }}

imovel.cpp

Código: C++
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
#include <iostream>#include "imovel.h"#include <sstream> using std::cout;using std::cin;using std::string;using std::stringstream; struct Timovel{    string codigo_imovel;    string codigo_cliente;    float iptu;    float valor_aluguel;    string situacao; }; Timovel *imovel_criar(){ Timovel *imovel = new Timovel;     if (imovel == NULL) {        cout << "Memória insuficiente!\n" << '\n';        exit(1);    } return imovel;} void imovel_destruir (Timovel *imoveis){     delete []imoveis;}  float receberValorFloat(string texto){    string temp="";    float num=0;    while (true){        cout <<  texto;        getline(cin, temp);        stringstream myStream(temp);        if (myStream >>num) break; //sucesso na conversão            else            cout << "\nNúmero inválido: (" << temp <<") Tente de novo." << '\n';    }   return num;} void imovel_imprimirTodos (Timovel *imovel, int total){    cout <<"Exibindo agora os dados gravados\n\n";    for (int i=0;i<total;i++){      imovel_imprimir(imovel, i);    } } void imovel_imprimir (Timovel *imovel, int numRec){     cout <<"Codigo Imovel: " << imovel[numRec].codigo_imovel <<'\n';    cout <<"Codigo Cliente: " << imovel[numRec].codigo_cliente <<'\n';    cout <<"Valor aluguel: " << imovel[numRec].valor_aluguel <<'\n';    cout <<"IPTU: " << imovel[numRec].iptu <<'\n';    cout <<"Situação: " << imovel[numRec].situacao <<'\n';    cout <<'\n'; }  void imovel_editar (Timovel *imovel, int numRec){     string texto;    cout <<"Editando imovel de código: " << imovel[numRec].codigo_imovel <<"\n\n";    cout <<"O valor atual de cada campo será exibido entre parênteses\n";    cout <<"Basta teclar ENTER para deixar esse campo inalterado\n\n";     cout <<"Codigo Cliente (" << imovel[numRec].codigo_cliente << "): ";    getline(cin, texto);    if (texto!="") imovel[numRec].codigo_cliente=texto;        cout <<"\nValor aluguel (" << imovel[numRec].valor_aluguel << "): ";    getline(cin, texto);    if (texto!="") imovel[numRec].valor_aluguel=stof(texto);     cout <<"\nIPTU (" << imovel[numRec].iptu <<  "): ";    getline(cin, texto);    if (texto!="") imovel[numRec].iptu=stof(texto);     cout <<"\nSituação (" << imovel[numRec].situacao <<  "): ";    getline(cin, texto);    if (texto!="") imovel[numRec].situacao=texto;    cout <<'\n'; } void imovel_adicionar(Timovel *&imovel, int *numRegistros, std::fstream *arq){    //Aumenta o tamanho do vetor em um elemento e preenche esse elemento     Timovel *temp = new Timovel[*numRegistros+1];    std::copy(imovel,imovel+*numRegistros,temp);     delete imovel;    imovel=temp;     //preenche o registro adicionado com os dados do imovel        //Como imoveis podem ser deletados, a partir do segundo imóvel o codigo de registro    // é determinado somando um ao código do imóvel anterior    if (*numRegistros <2) imovel[*numRegistros].codigo_imovel = *numRegistros;    else{        string codigo_imovel_anterior = imovel[(*numRegistros)-1].codigo_imovel;        imovel[*numRegistros].codigo_imovel=std::to_string(stoi(codigo_imovel_anterior)+1);    }    //imovel_cadastrar(&imovel[*numRegistros], *numRegistros);    if (arq==NULL){ //se não for definido um arquivo ao ser chamada a função, lê do prompt         cout <<"Código_Cliente: ";        getline(cin, imovel->codigo_cliente);         imovel->valor_aluguel=receberValorFloat("Valor Aluguel: ");        imovel->iptu=receberValorFloat("Valor IPTU: ");        cout <<"Situação: ";        getline(cin, imovel->situacao);        cout <<'\n';    }else{  //carrega do arquivo    string linha;        getline(*arq, imovel[*numRegistros].codigo_imovel);        getline(*arq, imovel[*numRegistros].codigo_cliente);        getline(*arq, linha);        imovel[*numRegistros].valor_aluguel=stof(linha);        getline(*arq, linha);        imovel[*numRegistros].iptu=stof(linha);        getline(*arq, imovel[*numRegistros].situacao);    }     *numRegistros=*numRegistros+1; } void imovel_deletar(Timovel *&imovel, int *numRegistros, int numRec){    //crio um novo vetor com um elemento a menos e copio do vetor antigo    //todos os elemmentos anteriores e posteriores ao registro a ser apagado    Timovel *temp = new Timovel[*numRegistros-1];    std::copy(imovel,imovel+numRec-1,temp);    std::copy(imovel+numRec,imovel+*numRegistros,temp+numRec-1);     delete imovel;    imovel=temp;    *numRegistros=*numRegistros-1; } float imovel_calcularFatura (Timovel *imovel, int numRec, string *codCliente, string *situacaoImovel){     *codCliente= imovel[numRec].codigo_cliente;    *situacaoImovel= imovel[numRec].situacao;        float aluguel = imovel[numRec].valor_aluguel;    float iptu = imovel[numRec].iptu;     float txAdm = 0.03;    if ((aluguel > 500) && (aluguel<=2000))txAdm=0.05;    if (aluguel <=500) txAdm=0.08;     float txBanco = 1.50;    if (aluguel >1000) txBanco=0.95;     float valorFatura = aluguel + iptu + (aluguel*txAdm) +txBanco;     cout <<"Situação: " << imovel[numRec].situacao <<'\n';    cout <<'\n';        return valorFatura; }

cliente.h

Código: C++
123456789101112
#include <fstream>using std::fstream;struct Tcliente; Tcliente *cliente_criar();void cliente_cadastrar (Tcliente *cliente, int indice);void cliente_imprimirTodos (Tcliente *cliente, int total);void cliente_imprimir (Tcliente *cliente, int numRec);//Defini um argumento default NULL para "arq" porque essa função só será chamada com//esse argumento na inicialização do programavoid cliente_adicionar(Tcliente *&cliente, int *numRegistros, fstream *arq=NULL);void cliente_destruir (Tcliente *cliente);

cliente.cpp

Código: C++
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
#include <iostream>#include "cliente.h" using std::cout;using std::cin;using std::string; struct Tendereco{  string logradouro;  string numero;  string complemento;  string cep;  string bairro;  string cidade;  string uf;}; struct Tcliente{    string nome;    string cpf;    int codigo_cliente;    Tendereco endereco; }; Tcliente *cliente_criar(){ Tcliente *cliente = new Tcliente;     if (cliente == NULL) {        cout << "Memória insuficiente!\n" << '\n';        exit(1);    } return cliente;} void cliente_destruir (Tcliente *clientes){     delete []clientes;}   void cliente_imprimirTodos (Tcliente *cliente, int total){    cout <<"Exibindo agora os dados gravados\n\n";    for (int i=0;i<total;i++){      cliente_imprimir(cliente, i);    } } void cliente_imprimir (Tcliente *cliente, int numRec){     cout <<"Código cliente: " << cliente[numRec].codigo_cliente <<'\n';    cout <<"Nome: " << cliente[numRec].nome <<'\n';    cout <<"CPF: " << cliente[numRec].cpf <<'\n';    cout <<"Endereço: " << cliente[numRec].endereco.logradouro <<", " <<cliente[numRec].endereco.numero ;    if (cliente[numRec].endereco.complemento !="") cout << ", " <<cliente[numRec].endereco.complemento;    cout <<"\n" <<cliente[numRec].endereco.bairro ;    cout <<"\n" <<cliente[numRec].endereco.cidade ;    cout <<"\n" <<cliente[numRec].endereco.uf ;    cout <<"\n" <<cliente[numRec].endereco.cep ;     cout <<"\n\n"; } void cliente_adicionar(Tcliente *&cliente, int *numRegistros, fstream *arq){    //Aumenta o tamanho do vetor em um elemento e preenche esse elemento     Tcliente *temp = new Tcliente[*numRegistros+1];    std::copy(cliente,cliente+*numRegistros,temp);     delete cliente;    cliente=temp;        //preenche o registro adicionado com os dados do cliente    cliente[*numRegistros].codigo_cliente=*numRegistros+1;    //cliente_cadastrar(&cliente[*numRegistros], *numRegistros);    if (arq==NULL){ //se não for definido um arquivo ao ser chamada a função, lê do prompt         cout <<"Nome: ";        getline(cin, cliente[*numRegistros].nome);        cout <<"CPF: ";        getline(cin, cliente[*numRegistros].cpf);        cout <<"Logradouro: ";        getline(cin, cliente[*numRegistros].endereco.logradouro);        cout <<"Número: ";        getline(cin, cliente[*numRegistros].endereco.numero);        cout <<"Complemento: ";        getline(cin, cliente[*numRegistros].endereco.complemento);        cout <<"Bairro: ";        getline(cin, cliente[*numRegistros].endereco.bairro);        cout <<"Logradouro: ";        getline(cin, cliente[*numRegistros].endereco.cidade);        cout <<"UF: ";        getline(cin, cliente[*numRegistros].endereco.uf);        cout <<"CEP: ";        getline(cin, cliente[*numRegistros].endereco.cep);        cout <<'\n';    }else{  //carrega do arquivo        getline(*arq, cliente[*numRegistros].nome);        getline(*arq, cliente[*numRegistros].cpf);        getline(*arq, cliente[*numRegistros].endereco.logradouro);        getline(*arq, cliente[*numRegistros].endereco.numero);        getline(*arq, cliente[*numRegistros].endereco.complemento);        getline(*arq, cliente[*numRegistros].endereco.bairro);        getline(*arq, cliente[*numRegistros].endereco.cidade);        getline(*arq, cliente[*numRegistros].endereco.uf);        getline(*arq, cliente[*numRegistros].endereco.cep);    }     *numRegistros=*numRegistros+1; } 

« Última modificação: Abril 26, 2019, 03:49:44 pm por Jefferson »
http://jefferson-ryan.blogspot.com
http://ryan.com.br

Se o que você escreve não merece sua atenção, vai merecer a atenção de quem?!

FORUM.RYAN.COM.BR

Aula 8 - Aplicação contextualizada
« Online: Abril 25, 2019, 01:37:04 pm »