AprendiNoLinux
(usa Ubuntu)
Enviado em 05/09/2011 - 00:52h
É com grande prazer que disponibilizo a versão 1.0 beta do sisteminha de lanchonete. Não é uma MacDonald's rsrs, mas da pro gasto.
É importante que se façam testes para ver se não tem algum BUG ou se pode melhorar algumas rotinas que foram feitas via POG.
No aprendizado eu procurei tentar carregar somente uma vez o arquivo físico e o restante foi feito usando-se variáveis e arrays em memória.
Estou tendo dificuldades para manobrar e formatar os dados para apresenta-los quando estão em arrays. Falo na questão do posicionamento de cada campo. Tratar alinhamento a direita está cruel rsrs.
Espero que gostem.
Para usar plenamente, sugiro salvar o arquivo com o nome cardapio.txt
Você pode salvar com outro nome e alterar a configuração que está no Script.
====cardapio.txt============================================================
Cachorro quente:100:120
Bauru com ovo:102:150
Hambúrger:103:120
Cheeseburguer:104:130
Bauru simples:101:130
Refrigerante:105:100
Beirute:106:1180
Copa de água:107:115
Chiclete:108:070
Cigarro Free:109:470
Misto Frio:110:290
Adeus Mamãe:111:050
Pinga Canabrava:112:001
Pastel de Queijo:113:245
=====fim======================
É importante que o arquivo cardapio.txt tenha um enter no final da última linha dos produtos. Percebi que se não for assim, no momento da leitura do cardápio, este item não irá entrar.
====Início cardapio.sh =============================
#!/bin/bash
# file: cardapio.sh
# author: Geraldo T. Albuquerque aka @GA_Tux ou @AprendinoLinux
# co-author: Hudson Moreira Guimaraes dos Santos aka @hudyfx
# version: 1.0 beta
# objetives: Script coleta a digitação de códigos de uma lanchonete.
# detalhes: Lembrei do Roberto Carlos rss. São tantas emoções....
# ----------------------------------------------------------------------------
# Desenvolva um programa em shell que leia o código do item pedido,
# a quantidade e calcule o valor a ser pago por aquele lanche.
# Considere que a cada execução somente será calculado um item.
# ----------------------------------------------------------------------------
# Roadmap e changelog:
# 1 - Criar uma lista com os produtos e seus preços. (ok)
# 2 - Carregar a lista de preço via arquivo (ok) grato ao @hudyfx
# 3 - Permitir escolher o produto na lista. (ok) grato ao @hudyfx
# 4 - Mostrar o sub-total que está dando a conta. (ok)
# 5 - Mostrar os itens escolhidos no pedido. (ok)
# 6 - Finalizar a comanda. (ok)
# 7 - Salvar o pedido temporário ok (está em memória)
# 8 - Salvar o pedido finalizado ? #FIXME Falta aprender aproveitar a tela.
# 9 - Montar ticket do pedido. (ok) Créditos ao @hudyfx
# 10- Configuração para usar vários arquivos de cardápio. (ok)
# ----------------------------------------------------------------------------
# XXX: Formatar a saída está uma dificuldade, alinhar a direita.
# XXX: Duas POGs foram criadas para quebrar o galho, mas não está legal.
# TODO: Falta criar um cabeçalho com os nomes de campos no arquivo cardapio.txt
# ----------------------------------------------------------------------------
# Variáveis globais
# ----------------------------------------------------------------------------
start=0 # Controla o início das digitações.
valor_pedido=0 # Acumula o valor do pedido em aberto.
tab_precos= # Armazenar a tabela completa com preços , códigos e nomes.
_itens_pedido= # Coleta os itens digitados no pedido.
cont_iped="0" # Contador de itens no pedido.
# ----------------------------------------------------------------------------
# Configs para o arquivo de cardápio.
# ----------------------------------------------------------------------------
_CONF_CARDAPIO="cardapio.txt"
_DIR_CARDAPIO="${PWD}"
_FILE_CARDAPIO="${_DIR_CARDAPIO}/${_CONF_CARDAPIO}"
# ----------------------------------------------------------------------------
# Reconfigura as variáveis globais após fechar e finalizar o pedido.
function inicializa()
{
valor_pedido="0"
cont_iped="0"
_itens_pedido=
start=0
}
# Executa rotina de impressão e finalização do pedido. Cobra até imposto rsrs.
# Não cobra o imposto, mas poderia cobrar. Fica como desafio para alguém.
function finaliza()
{
if [ "$valor_pedido" -gt 0 ]
then
# Neste ponto poderá adicionar a gravação ou impressão do pedido.
ped_numero=$(date +"%s")
clear
echo "+=========================================+"
echo "|Finalizando o Pedido nº.....: ${ped_numero} |"
echo "+=========================================+"
echo "|Deseja nota fiscal paulista ? kkkkk |"
echo "+---+-------------------------------+-----+"
echo "|Cod| Produto |Preço|"
echo "+---+-------------------------------+------"
itens_do_pedido
echo "+---+-------------------------------+------"
echo " Total da fatura....................: ${valor_pedido}"
echo "+=========================================+"
echo "|Impostos a pagar: Iss, icms, pis, cofins |"
echo "+=========================================+"
read -t 10
inicializa
return
else
echo ""
echo "================================================="
echo "Você não digitou nenhum pedido ainda."
echo "Está com pressa ? rsrs "
echo "================================================="
read -t 5
fi
}
# Se o seek na tabela de memória falhar, vai alertar o usuário.
function naoexiste()
{
echo ""
echo "Produto $numero não existe, confira o cardápio !!! "
read -t 5
}
# Responsável por armazenar os itens no arquivo de memória dos pedidos.
# Note que se desejar armazenar em disco, é muito fácil nesta estrutura.
function digitei()
{
# Agora validando o código do produto com base no arquivo de tabela de preços.
# Apreoveita a tabela que já está em memória. (Desafio pessoal)
# Usar uma tabela armazenada em disco é fácil, difícil é controlar em memória.
for meuvalor in ${tab_precos[@]}
do
meu_cod=$(echo ${tab_precos[$numero]} | cut -d: -f1)
meu_nome_prod=$(echo ${tab_precos[$numero]} | cut -d: -f2)
meu_preco=$(echo ${tab_precos[$numero]} | cut -d: -f3)
if [ "$meu_cod" = "$numero" ]
then
valor_pedido=$((valor_pedido + meu_preco))
#Salvando os itens do pedido.
cont_iped=$((cont_iped +1))
# Que POG lascada, mas não conheço outra forma de fazer.
SEPA1="|"
SEPA2=" |"
if [ ${#meu_preco} -eq 4 ]
then
posit=${SEPA1}
else
posit=${SEPA2}
fi
_itens_pedido["$cont_iped"]="|${meu_cod}| ${meu_nome_prod}| ${meu_preco}${posit}"
# Salva o novo valor digitado. Não importa se é repetido ou não.
digitando["$contador"]="$1"
# Faz incremento do contador para o próximo passo.
let contador++
return
fi
done
naoexiste ; return
}
# Mostra os códigos já digitados e o valor acumulado do pedido.
function digitado()
{
if [ $start = "0" ]
then
start="1"
return
fi
echo "Produtos digitados.: ${digitando[@]} "
echo "Sub-Total é........: ${valor_pedido} "
}
# Área principal da digitação. Deste local pode-se ir a qualquer lugar.
function digitar()
{
while true
do
clear
mostramenu
digitado
echo ""
echo -n "Digite o código do produto...:"
read numero
if test $numero -gt 0
then
digitei $numero
digitado
else
_opcoes "$numero"
mostramenu
fi 2> /dev/null
done
}
# Fica como desafio para alguém que queira praticar.
# XXX: Falta dominar o processo de salvar usando as linhas de echo + tela.
function salva_pedido()
{
: # Caso precise salvar o pedido finalizado.
}
# XXX: Tenho dificulade em salvar o pedido linha a linha usando as telas.
function salva_tmp()
{
: # Caso precise salvar o pedido temporário.
}
# Prepara a chamada para listar o andamento do pedido.
function listar()
{
if [ "$valor_pedido" -gt 0 ]
then
listar_pedido
else
echo ""
echo "================================================="
echo "Você não digitou nenhum pedido ainda."
echo "Está com pressa ? rsrs "
echo "================================================="
read -t 5
fi
}
# Efetiva a listagem do pedido neste momento.
function listar_pedido()
{
clear
echo "+=========================================+"
echo "|Pedido digitado |"
echo "+=========================================+"
echo ""
echo "+---+-------------------------------+-----+"
echo "|Cod| Produto |Preço|"
echo "+---+-------------------------------+------"
itens_do_pedido
echo "+---+-------------------------------+------"
echo " Sub-total do pedido................: ${valor_pedido}"
echo "+=========================================+"
echo -n " ENTER retorna ao pedido."
read
return
}
# Contém os produtos digitados e já formatado para o padrão da saída.
# TODO: Valores quando formam gravados não estão alinhados a direita.
# TODO: Aqui a recuperação é apenas a leitura do array em memória.
function itens_do_pedido()
{
local i
i="1"
while true
do
if [ "${#_itens_pedido[$i]}" -gt 0 ]
then
echo "${_itens_pedido[$i]} "
else
# Acabou o pedido, posso sair.
return
fi
let i++
done
return
}
# Dá de pinote do sistema. Agora com mais équio.
# FIXME: Se tem pedido em aberto, não avisa o usuário.
# FIXME: Próxima versão precisa fazer esta verificação.
function sair()
{
echo ""
echo "+---------------------------------------------------------+"
echo "|Finalizando o sistema bye. Digitação não foi gravada !!! |"
echo "|É importante verificar se não existe um pedido em aberto.|"
echo "|Fica como pendência a ser resolvida |"
echo "+---------------------------------------------------------+"
read -t 0.5
exit
}
# Quase todos os erros levam a esta tela genérica.
function erro()
{
echo ""
echo "+------------------------------------------------------+"
echo "|Opção digitada é inválida |"
echo "|Precisa de ajuda ? use o help |"
echo "+------------------------------------------------------+"
read -t 2
}
# XXX: Uma tremenda POG para fazer a manobra no posicionamento.
# XXX: Não encontrei uma forma melhor para posicionar os produtos e valores.
# XXX: Se alguém quiser colaborar com algum regex ou uma nova forma, avise.
function completa_texto()
{
#------------------------------------------------------------------------------
# Recebe o Tamanho total = tt (numérico)
# Recebe a String a ser tratada = ts
# Calcula o Tamanho a completar = (tt -ts)
# Exemplo: Se um texto é "cachorro quente" ele tem 15 de tamanho preenchido.
# Se o tamanho do campo é de 30, vou completar com 15 ???.
#------------------------------------------------------------------------------
if [ "$1" = "-h" ]; then
# Solicitando Ajuda para usar a função.
clear
echo "+------------------------------------------------------+"
echo "|Ajuda para usar a função completa_texto |"
echo "+------------------------------------------------------+"
echo "|Uso: completa_texto 20 'seu texto' '.' 'D' |"
echo "+------------------------------------------------------+"
echo "|Útil quando você pega 1 campo do banco de dados. |"
echo "|Formatar a linha com um determinado tamanho desejado. |"
echo "|Se você conhece algum regex para completar, me avise. |"
echo "|Você pode completar com qualquer caracter - o espaço. |"
echo "+------------------------------------------------------+"
echo "|Exemplos: Seu campo de texto para usar no Script é de |"
echo "|20 caracteres. No banco esta com 17 apenas. |"
echo "|Meu texto exemplo. Quando completar ficará: |"
echo "|Meu texto exemplo... |"
echo "+------------------------------------------------------+"
echo "|A informação do banco vem com 25 caracteres. |"
echo "|Meu texto é muito grande. |"
echo "|Ficará assim: Meu texto é muito... |"
echo "+------------------------------------------------------+"
read -t 10
exit
fi
# Valida o recebimento de parâmetros de forma controlada.
if [ "$#" -gt 2 ]
then
# Variáveis de trabalho.
_tt="$1" # Tamanho que o texto deverá retornar.
_var_tmp="$2" # Texto recebido
_completar="$3" # caracter que será usado no completar.
# Avalia se o 1º parâmetro é um número.
if [ $((_tt)) -gt 0 ]
then
# Confere se realmente enviou apenas 1 caracter.
# Se enviou mais de 1 caracter, não sabe o que faz.
if [ "${#_completar}" -gt 1 ]
then
echo "Só pode receber 1 caracter para completar"
echo "Veja o que você está fazendo com: $3"
sleep 5
return 1 # Erro grave.
fi
# Forçando a verificação do tamanho recebido.
# Se ele for >= ao total, será cortada.
if [ "${#_var_tmp}" -ge "${_tt}" ]
then
_var_tmp=${_var_tmp:0:_tt-3}
fi
# Executando o complemento do texto solicitado.
_vl_texto=${#_var_tmp}
_falta=$((_tt - _vl_texto))
i="1"
_tmp_texto=$_completar
while test $i -lt $_falta
do
let i++
_tmp_texto="${_tmp_texto}${_completar}"
done
# Efetua o preenchimento a direita ou esquerda.
# Parâmetro é opcional. Default é completar a direita.
if [ "$4" = "E" ]
then
_texto_completo="${_tmp_texto}${_var_tmp}"
else
_texto_completo="${_var_tmp}${_tmp_texto}"
fi
echo "${_texto_completo}"
else
clear
echo "+-------------------------------------------+"
echo "| Este parâmetro tem que ser numérico: $_tt * "
echo "| Verifique o que você está errado. |"
echo "| Texto será retornado sem alterações |"
echo "| Por este motivo, se vira nos 30 zé. |"
echo "+-------------------------------------------+"
echo "$_var_tmp"
read -t 5
return 1 # Retornando erro pro zé.
fi
else
clear
echo "+------------------------------------------------------+"
echo "|Não enviou a quantidade de parâmetros correta !!! |"
echo "+------------------------------------------------------+"
echo "|1º) Numérico. Indica o tamanho que o texto ficará |"
echo "|2º) String do texto ou valor do texto a completar. |"
echo "|3º) Qual o caracter que será usado para completar. |"
echo "|4º) Completa Char. 'D'ireita ou 'E'squerda,opcional. |"
echo "+------------------------------------------------------+"
echo "|Operação não será efetuada até acerto dos parâmetros. |"
echo "+------------------------------------------------------+"
read -t 5
return 1 # Indica que houve um erro fatal.
fi
}
# Tabela de preços. Usada para consulta e busca.
# Ficou até bacana a forma de gravar. Peca no posicionamento dos valores.
function tabela_de_precos()
{
# Pegar o arquivos cardapio.txt e trabalhar seus dados no formato.
# Tentar fazer ele ser aproveitado em rotinas posteriores.
while read linha;do
# Monto um array para usar como tabela e indexador para seek.
# Tratar valores de campo para compor a linha formatada.
cod_prod=$(echo $linha | cut -d: -f2)
pre_prod=$(echo $linha | cut -d: -f3)
nom_prod=$(echo $linha | cut -d: -f1)
nom_completo=$(completa_texto 30 "${nom_prod}" ".")
tab_precos[${cod_prod}]="${cod_prod}:${nom_completo}:${pre_prod}" # Armazenar só preços.
# FIXME: variável #POG para contornar tamanho de impressão.
tp="6"
# Só mostra na tela caso não seja chamado pelo processo de carga.
if [ "$1" = "carga" ]
then
:
else
printf "%0s%-31s%-$((${#pre_prod} - ${tp}))s%-5s%-10s\n" \
"|$cod_prod|" " $nom_completo" "|" "$pre_prod|"
fi
done < "$_FILE_CARDAPIO" # Usa arquivo parametrizado.
}
# Tela genérica para o cardápio. Note que trabalha sempre em memória.
function cardapio()
{
clear
echo "+=========================================+"
echo "|Cardápio lanchonete modelo Canabrava |"
echo "+=========================================+"
echo ""
echo "+---+-------------------------------+-----+"
echo "|Cod| Produto |Preço|"
echo "+---+-------------------------------+------"
tabela_de_precos
echo "+---+------------------------------.+-----+"
echo -n "Enter retorna onde você estava "
read
}
# Sem novidade. Tela central do menu. É reaproveitado em vários locais.
function mostramenu()
{
clear
echo "========================================"
echo "Menu Principal"
echo "========================================"
echo ""
echo "c - Mostra Cardápio"
echo "d - Digitar pedido"
echo "l - Lista o pedido"
echo "f - Finaliza o pedido"
echo "s - Sair"
echo "h - Ajuda"
echo ""
if [ "$1" ]; then echo -n "Escolha a opção:" ; fi
}
# Esta função não ajuda patavinas, rrs, mas serve de exemplo como fazer.
# Se for o caso, a aplicação pode montar parâmetros e tratar este local.
function ajuda()
{
echo ""
echo "+------------------------------------+"
echo "|Coloque aqui as opções de ajuda |"
echo "|Dicas de uso para o protosuário !!! |"
echo "+------------------------------------+"
read -t 5
return
}
# Generalizando as opções para ser reaproveitada em mais de um local.
function _opcoes()
{
# Recebe 1 parâmetro para saber o local onde está. exemplos:
# Menu principal é escolha. "$escolha", na Digitação é "$numero"
case "$1" in
c) cardapio ;;
d) digitar ;;
l) listar ;;
f) finaliza ;;
s) sair ;;
h) ajuda ;;
*) erro ;;
esac
}
function _menu()
{
clear
while true
do
mostramenu normal
read escolha
_opcoes "$escolha"
done
}
# O sistema só vai trabalhar se encontrar a tabela do cardápio.
function achou_tabela()
{
if test -e "${_FILE_CARDAPIO}"
then
# Achou a tabela com o cardápio, vai trabalhar.
tabela_de_precos carga # Força carregar a tabela de preços.
else
# Falhou a busca pelo arquivo, sistema irá abortar.
echo ""
echo "+------------------------------------+"
echo "|Não encontrou a tabela do cardápio: |"
echo "|Config: ${_CONF_CARDAPIO} |"
echo "+------------------------------------+"
read -t 5
exit
fi
}
function main()
{
achou_tabela # Verifica a existência da tabela do cardápio.
_menu # Menu principal
}
main "${@#}"
exit
========= fim cardapio.sh ================================
Não se engane. Esta versão vem com muitos detalhes extras.
@GA_Tux