terça-feira, 29 de junho de 2010

sábado, 19 de junho de 2010

ControlToy v.1

Depois de algumas madrugadas a dentro e "perdendo" algumas aulas de ditado na faculdade, consegui concluir meu primeiro projeto em linguagem C usando a IDE Dev-C++, para a faculdade. Um programa para gerenciamento de loja com controle de estoque, caixa, entrada de produtos e listagem de com paginação!

Tela Principal

Código Fonte

ControlToy v.1.c
Onde é chamado os métodos correspondentes a opção selecionada pelo usuário.
/*
 * ControlToy v.1 - 2010
 * Desenvolvido por Marcelo L. Filho ( Idemax )
 * idemax@idemax.net - www.idemax.net
 * Todos os direitos intelectuais reservados ao uso educacional.
 */

#include "includes.c"

void main()
{
    char option;
    
    // Descomente a linha abaixo para o programa cadastrar 100 produtos automaticamente.    
    // testProducts();
    
    while(option != '6')
    {
        system("cls");
        
        printf("\n\t------------------");
        printf("\n\t| ControlToy v.1 |");
        printf("\n\t------------------");
        
        printf("\n\n\tMENU PRINCIPAL\n");
        printf("\n\t1) Cadastrar Produtos");
        printf("\n\t2) Frente de Caixa");
        printf("\n\t3) Consultar Estoque");
        printf("\n\t4) Entrada de Produtos");
        printf("\n\t5) Listagem de Produtos");
        printf("\n\t6) Sair");
        printf("\n\n\tSelecione a opcao desejada: ");
        fGetCH(&option);
        
        switch(option)
        {
            case '1': // Cadastrar Produtos
                createNewProduct();
                break;
            case '2': // Frente de Caixa
                cashier();
                break;
            case '3': // Consultar Estoque
                checkStock();
                break;
            case '4': // Entrada de Produtos
                entryProduct();
                break;
            case '5': // Listagem de Produtos
                listProducts();
                break;
            case '6': // Sair
                if( !confirm(CONFIRMACAO_SAIR, 1) )
                    option = 0;
                break;
            default:
                alert(OPCAO_INVALIDA, 1);
                break;
        }
    }
}

includes.c
Aqui é concentrado todos os includes necessários para o funcionamento do programa.
/*
 * ControlToy v.1 - 2010
 * Desenvolvido por Marcelo L. Filho ( Idemax )
 * idemax@idemax.net - www.idemax.net
 * Todos os direitos intelectuais reservados ao uso educacional.
 */

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <math.h>

#include "Constants.c"
#include "Prototypes.c"
#include "Structs.c"
#include "db.c"
#include "Utils.c"
#include "Functions.c"

Constants.c
Constantes usadas no programa avisar e informar o usuário.
/*
 * ControlToy v.1 - 2010
 * Desenvolvido por Marcelo L. Filho ( Idemax )
 * idemax@idemax.net - www.idemax.net
 * Todos os direitos intelectuais reservados ao uso educacional.
 */

// menu
#define OPCAO_INVALIDA   "Opcao invalida!"

// db
#define FIRST_ID   100
#define DB_SIZE    500

// novo produto
#define PRODUTO_SUCESSO     "Produto cadastrado com sucesso!"
#define QTD_PAGINACAO       5

// caixa
#define QUANTIA_INDISPONIVEL    "Quantidade nao disponivel em estoque!"
#define INSERIR_NOVO            "Deseja inserir novo produto na lista de compra? ( s:SIM, n:NAO )"
#define FINALIZAR_LISTA         "Deseja finalizar a lista de compra? ( s:SIM, n:NAO )"
#define NOVO_PRODUTO_CAIXA_ERRO "Produto ja existe da lista de compra!"
#define NAO_HA_PRODUTOS_CAIXA   "Nao existem produtos cadastrados na lista de compra!"
#define CONFIRMAR_LISTA_COMPRA  "Efetuar saida dos produtos e baixa em estoque? ( s:SIM, n:NAO )"
#define NOVA_LISTA              "Deseja iniciar uma nova lista de compra? ( s:SIM, n:NAO )"
#define VENDA_FINALIZADA        "Saida de produtos efetuada com sucesso!"

// consulta
#define ID_NAO_ENCONTRADO   "Produto nao encontrado, tente novamente!"
#define CONTINUAR_BUSCA     "Deseja consultar outro produto? ( s:SIM, n:NAO )"

// entrada
#define ENTRAR_OUTRO    "Novos dados gravados com sucesso!\n\n\tDeseja da entrada em outro produto? ( s:SIM, n:NAO )"
#define CONFIRMAR_INFO  "Deseja alterar os valores de compra e venda do produto? ( s:SIM, n:NAO )"

// lista
#define NUMERO_PRE_CADASTRO 100
#define SAIR_LISTAGEM       "Pressione qualquer tecla para voltar ao menu inicial..."
#define NAO_HA_PRODUTOS     "Nao existe produto cadastrado!"

// sair
#define CONFIRMACAO_SAIR "Tem certeza que deseja sair? ( s:SIM, n:NAO )"

Prototypes.c
Mantém as assinaturas dos métodos que são necessários antes da implementação.
/*
 * ControlToy v.1 - 2010
 * Desenvolvido por Marcelo L. Filho ( Idemax )
 * idemax@idemax.net - www.idemax.net
 * Todos os direitos intelectuais reservados ao uso educacional.
 */

void alert(char text[], char cleanScreen);
float *sumPurchases(); // [0]: quantidade total, [1]: valor total
void completeShoppingList();

Structs.c
Estruras necessárias para tipar conjuntos de dados.
/*
 * ControlToy v.1 - 2010
 * Desenvolvido por Marcelo L. Filho ( Idemax )
 * idemax@idemax.net - www.idemax.net
 * Todos os direitos intelectuais reservados ao uso educacional.
 */

typedef struct products
{
    int id;
    char description[100];
    float sale, purchase;
    int stored;
}product;

db.c
Variáveis e métodos usados para gerenciar as entradas e saídas de dados do vetor que guarda os produtos.
/*
 * ControlToy v.1 - 2010
 * Desenvolvido por Marcelo L. Filho ( Idemax )
 * idemax@idemax.net - www.idemax.net
 * Todos os direitos intelectuais reservados ao uso educacional.
 */

int id = FIRST_ID, index = 0, cashierIndex = 0, cashierProducts[DB_SIZE][2];
product products[DB_SIZE];

int getNewId()
{
    return ++id;
}

void insertNewProduct(product newProduct)
{
    newProduct.id = getNewId();
    
    products[index] = newProduct;
    
    index++;
}

void insertNewProductVariables(char description[], float sale, float purchase, int stored)
{
    product newProduct;
    
    strncpy(newProduct.description, description, 100);
    newProduct.sale = sale;
    newProduct.purchase = purchase;
    newProduct.stored = stored;
    
    insertNewProduct( newProduct );
}

int verifyProductID( int pID )
{
    int i, rtn = 0, found = 0;
    product prod;
    
    for(i = 0; i < index; i++)
    {
        if(pID == products[i].id)
        {
            rtn = pID;
            found = 1;
            break;
        }
    }
    
    if( !found )
    {
        alert(ID_NAO_ENCONTRADO, 1);
        return -1;
    }
    
    return rtn;
}

int getProductByID( int pID )
{
    int i, rtn = 0, found = 0;
    product prod;
    
    for(i = 0; i < index; i++)
    {
        if(pID == products[i].id)
        {
            rtn = i;
            found = 1;
            break;
        }
    }
    
    if( !found )
    {
        alert(ID_NAO_ENCONTRADO, 1);
        return -1;
    }
    
    return rtn;
}

float getProductSellingPrice(int pID)
{
    float rtn = 0.0;
    int i;

    for(i = 0; i < index; i++)
    {
        if(pID == products[i].id)
        {
            rtn = products[i].sale;
            break;
        }
    }
    
    return rtn;
}

void startNewCashier()
{
    int i;
    
    for(i = 0; i < DB_SIZE; i++)
    {
        cashierProducts[i][0] = -1;
        cashierProducts[i][1] = -1;
    }
    
    cashierIndex = 0;
}

void inserNewCashierProduct(int pID, int qtd)
{
    cashierProducts[cashierIndex][0] = pID;
    cashierProducts[cashierIndex][1] = qtd;
    
    cashierIndex++;
}

int hasProductInCashier(int pID)
{
    int i;
    
    for(i = 0; i < cashierIndex; i++)
        if(cashierProducts[i][1] == pID)
            return 1;
    
    return 0;
}

Utils.c
Métodos e variáveis usadas globalmente pelo programa, para auxiliar no feedback do usuário e na execução de operações.
/*
 * ControlToy v.1 - 2010
 * Desenvolvido por Marcelo L. Filho ( Idemax )
 * idemax@idemax.net - www.idemax.net
 * Todos os direitos intelectuais reservados ao uso educacional.
 */

// Mostra uma mensagem na tela
void alert(char text[], char cleanScreen)
{
    if(cleanScreen)
        system("cls");
        
    printf("\n\n\n\t*** AVISO ***\n\n\t%s\n\n\n\n\t", text);
    system("pause");
}

void pause(char text[])
{
    printf("%s", text);
    fflush(stdin);
    getch();
}

void fGetCH(char * value)
{
    fflush(stdin);
    *value = getch();
}

void fGetS(char * value)
{
    fflush(stdin);
    gets(value);
}

int confirm(char text[], char cleanScreen)
{
    int rtn = 0;
    char choice;
    
    if(cleanScreen)
        system("cls");
    
    printf("\n\n\n\t*** ATENCAO ***\n\n\t%s\n\t", text);
    fGetCH(&choice);
    
    if(choice == 'S' || choice == 's' || choice == 13)
        rtn = 1;
    
    return rtn;
}

int stopPagination(int cPage, int tPage)
{
    int rtn = 1;
    char key;
    
    printf("\n\tPagina %i de %i.\n\tQualquer tecla: proxima pagina \\ ESQ: menu principal", cPage, tPage);    
    fGetCH(&key);
    
    if(key == 27)
        rtn = 0;
        
    return rtn;
}

void showProductInfo(int pID)
{
    printf("\t[%i] %s\n\t\tVenda R$ %.2f - Compra R$ %.2f // Estoque: %d unidades\n\n", products[pID].id, products[pID].description, products[pID].sale, products[pID].purchase, products[pID].stored);
}

void showCashierProductInfo(int pID)
{
    int correctID = getProductByID(cashierProducts[pID][0]);
    
    printf("\t[%i] %s\n\t\tQuantidade: %i unidades - Total: R$ %.2f\n\n", products[correctID].id, products[correctID].description, cashierProducts[pID][1], cashierProducts[pID][1] * products[correctID].sale);
}

int closeShoppingList()
{
    if(cashierIndex == 0)
    {
        alert(NAO_HA_PRODUTOS_CAIXA, 1);
        return 0;
    }
    
    int listIndex = 0, i, cPage = 1, tPage, rest, rtn = 1;
    
    tPage = cashierIndex / QTD_PAGINACAO;
    rest = cashierIndex % QTD_PAGINACAO;
    
    if(rest < 5)
        tPage++;
    else
        tPage--;
    
    for(i = 0; i < cashierIndex; i++)
    {
        if(listIndex == 0)
        {
            system("cls");
            
            printf("\n\t--------------------");
            printf("\n\t| FINALIZAR COMPRA |");
            printf("\n\t--------------------\n\n");
        }
        
        if(listIndex < QTD_PAGINACAO)
        {
            showCashierProductInfo(i);
            listIndex++;
        }
        
        if(listIndex >= QTD_PAGINACAO)
        {
            if( !stopPagination(cPage, tPage) )
                break;

            cPage++;
            listIndex = 0;
        }
        
        if(listIndex != 0 && i == cashierIndex - 1)
        {
            float *sum = sumPurchases();
            
            printf("\n\tPagina %i de %i.\n\n\t-------------------------------------------------------\n\tFIM DA LISTA DE COMPRA\n\n\tTotal de produtos: %.0f - Total da compra: R$ %.2f\n", cPage, tPage, sum[0], sum[1]);
            
            if(confirm(CONFIRMAR_LISTA_COMPRA, 0))
                completeShoppingList();
            else
                rtn = 0;
        }
    }
    
    return rtn;
}

float *sumPurchases() // [0]: quantidade total, [1]: valor total
{
    float *rtn, qtd = 0.0, pSum = 0, saleValue, result[2];
    int i;
    
    for(i = 0; i < cashierIndex; i++)
    {
        qtd += cashierProducts[i][1];
        
        saleValue = getProductSellingPrice(cashierProducts[i][0]);
        pSum += saleValue * cashierProducts[i][1];
    }
    
    result[0] = qtd;
    result[1] = pSum;
    
    rtn = &result;
    
    return rtn;
}

void completeShoppingList()
{
    int i, productID;
    
    for(i = 0; i < cashierIndex; i++)
    {
        productID = getProductByID(cashierProducts[i][0]);
        products[productID].stored -= cashierProducts[i][1];
    }
    
    alert(VENDA_FINALIZADA, 1);
}

Functions.c
Métodos e variáveis do menu principal.
/*
 * ControlToy v.1 - 2010
 * Desenvolvido por Marcelo L. Filho ( Idemax )
 * idemax@idemax.net - www.idemax.net
 * Todos os direitos intelectuais reservados ao uso educacional.
 */

// popula o DB de produtos para testes
void testProducts()
{
    int i, n, t = NUMERO_PRE_CADASTRO;
    product testProduct;
    
    for(i = 0; i < t; i++)
    {
        n = i + 1;
        insertNewProductVariables("Produto", n*4, n*2, n*6);
    }
}

// 1- Cadastrar Produtos
void createNewProduct()
{
    system("cls");
    
    product newProduct;
    
    printf("\n\t--------------------------");
    printf("\n\t| CADASTRAR NOVO PRODUTO |");
    printf("\n\t--------------------------\n");
    printf("\n\n\tDigite a descricao do produto:\n\t");
    
    fGetS( newProduct.description );
    
    printf("\n\n\tDigite o valor de compra do produto:\n\t");
    scanf("%f", &newProduct.purchase);
    
    printf("\n\n\tDigite o valor de venda do produto:\n\t");
    scanf("%f", &newProduct.sale);
    
    printf("\n\n\tDigite a quantia que o produto tem em estoque:\n\t");
    scanf("%d", &newProduct.stored);
    
    insertNewProduct( newProduct );
    
    printf("\n\n\tNovo produto \"%s\" cadastrado com o ID: %i\n\n\t", newProduct.description, id);
    system("pause");
    
    alert(PRODUTO_SUCESSO, 1);
}

// 2- Frente de Caixa
void cashier() // cashier = caixa de supermercado ( http://www.liveenglishprogram.com/caixa.html )
{
    startNewCashier();
    
    int continueRegistration = 1, listSize = cashierIndex, pID, qtd, qtdError;
    
    while( continueRegistration )
    {
        system("cls");
        
        printf("\n\t-------------------");
        printf("\n\t| FRENTE DE CAIXA |");
        printf("\n\t-------------------\n\n");
        
        printf("\tProdutos da lista: %i", listSize);
        
        printf("\n\n\tDigite o ID do produto a ser inserido:\n\t\t( 0: menu principal, 1: finalizar lista )\n\t");
        scanf("%i", &pID);
        
        if( pID == 0 )
            return;
            
        if( pID != 1 ) // novo produto da lista
        {
            pID = verifyProductID(pID);
            
            if(pID > -1)
            {
                if( hasProductInCashier(pID) )
                {
                    alert(NOVO_PRODUTO_CAIXA_ERRO, 1);
                    continue;
                }
                
                qtdError = 1;
                while( qtdError )
                {
                    printf("\n\n");
                    showProductInfo(getProductByID(pID));
                    
                    printf("\tDigite a quantidade comprada: ");
                    scanf("%i", &qtd);
                    
                    if( qtd > products[getProductByID(pID)].stored )
                        alert(QUANTIA_INDISPONIVEL, 0);
                    else
                        qtdError = 0;
                }
                
                inserNewCashierProduct(pID, qtd);
                
                listSize = cashierIndex;
                
                if(confirm(INSERIR_NOVO, 1))
                {
                    continue;
                }
                else if(confirm(FINALIZAR_LISTA, 0))
                {
                    if(!closeShoppingList() && confirm(NOVA_LISTA, 1))
                        cashier();
                    
                    continueRegistration = 0;
                }
                else
                {
                    continueRegistration = 0;
                }
            }
        }
        else // finaliza a lista
        {
            if(listSize != 0 && !closeShoppingList() && confirm(NOVA_LISTA, 1))
                cashier();
            
            continueRegistration = 0;
        }
    }
}

// 3- Consultar Estoque
void checkStock()
{
    system("cls");
    
    printf("\n\t---------------------");
    printf("\n\t| CONSULTAR ESTOQUE |");
    printf("\n\t---------------------\n\n");
    
    int pID;
    
    printf("\tDigite o ID do produto a ser consultado ( 0: menu principal ):\n\t");
    scanf("%i", &pID);
    
    if( pID == 0 )
        return;
        
    pID = getProductByID(pID);
        
    if(pID > -1)
    {
        printf("\n\n");
        showProductInfo(pID);
        
        if(!confirm(CONTINUAR_BUSCA, 0))
            return;
    }
    
    checkStock();
}

// 4- Entrada de Produtos
void entryProduct()
{
    system("cls");
    
    printf("\n\t-----------------------");
    printf("\n\t| ENTRADA DE PRODUTOS |");
    printf("\n\t-----------------------\n\n");
    
    int pID;
    
    printf("\tDigite o ID do produto a ser dada entrada ( 0: menu principal ):\n\t");
    scanf("%i", &pID);
    
    if( pID == 0 )
        return;
        
    pID = getProductByID(pID);
        
    if(pID > -1)
    {
        printf("\n\n");
        showProductInfo(pID);
        
        float sale, purchase;
        int stored;
        
        printf("\tDigite a quantidade de produtos que esta sendo adquirida:\n\t");
        scanf("%i", &stored);
        
        products[pID].stored  += stored; //  No PDF pedia a quantidade adquirida nao a nova quantidade, por isso é adicionado a quantidade atual, nao atualizado.
        
        /*
        Contribuição abaixo de Xandão ( http://www.twitter.com/xandao_luchetti )
        */
        if(!confirm(CONFIRMAR_INFO, 0))
            return;
        
        printf("\n\n\tDigite o novo preco de compra:\n\t");
        scanf("%f", &purchase);
        
        printf("\n\n\tDigite o novo preco de venda:\n\t");
        scanf("%f", &sale);
        
        products[pID].purchase = purchase;
        products[pID].sale     = sale;
        
        if(!confirm(ENTRAR_OUTRO, 0))
            return;
    }
    
    entryProduct();
}

// 5- Listagem de Produtos
void listProducts()
{
    if(index == 0)
    {
        alert(NAO_HA_PRODUTOS, 1);
        return;
    }
    
    int listIndex = 0, i, cPage = 1, tPage, rest;
    
    tPage = index / QTD_PAGINACAO;
    rest = index % QTD_PAGINACAO;
    
    if(rest < 5)
        tPage++;
    else
        tPage--;
    
    for(i = 0; i < index; i++)
    {
        if(listIndex == 0)
        {
            system("cls");
            
            printf("\n\t------------------------");
            printf("\n\t| LISTAGEM DE PRODUTOS |");
            printf("\n\t------------------------\n\n");
        }
        
        if(listIndex < QTD_PAGINACAO)
        {
            showProductInfo(i);
            listIndex++;
        }
        
        if(listIndex >= QTD_PAGINACAO)
        {
            if( !stopPagination(cPage, tPage) )
                break;

            cPage++;
            listIndex = 0;
        }
        
        if(listIndex != 0 && i == index - 1)
        {
            printf("\n\tPagina %i de %i.\n\t", cPage, tPage);
            pause(SAIR_LISTAGEM);
        }
    }
}

Baixe os códigos fontes: ControlToy v.1.rar (16.39 KB)