Catalog · How the catalog works
Delphi-PedidoVenda
Omie - Pedido de Venda
- ★ 1 on GitHub
Anyone may press Interesting, signed in or not. It helps others find this project.
README
Delphi — Pedido de Venda
Teste técnico para a vaga de Analista Desenvolvedor Delphi.
Aplicação desktop desenvolvida em Delphi com persistência em Firebird 4.0 via FireDAC, organizada em camadas (Repository/Service), seguindo Clean Code e queries 100% parametrizadas.
Links para ferramentas utilizadas:
Detalhes extras
- [x] Arquivos SQLs para criação da base dados
- [x] Sem utilização de componentes de terceiros
- [x] Utilização de componentes mais simples do Delphi (TStringGrid ao invés de TDBGrid, por exemplo)
- [x] Lisagem de pedidos com total geral
- [x] Botão de cancelar pedido
- [x] Testes unitários com DUnitX
- [x] Commits detalhados no Github com criação de PR para exemplificar processo de desenvolvimento
- [x] Documentação completa
Índice
- Pré-requisitos
- Estrutura do projeto
- Criando o banco de dados
- Configurando o INI
- Executando o projeto
- Roteiro de testes manuais
- Executando os testes unitários
- Decisões técnicas relevantes
Pré-requisitos
| Ferramenta | Versão mínima |
|---|---|
| Delphi | 10.4 Sydney ou superior |
| Firebird Server | 4.0 |
| fbclient.dll | 4.0 (incluída em /bin) |
Estrutura do projeto
Delphi-PedidoVenda/
???
????????? bin/
??? ????????? fbclient.dll # Client library Firebird 4.0
??? ????????? config.ini.example # Modelo de configura????o
???
????????? database/
??? ????????? create-database.sql # Cria o arquivo .fdb
??? ????????? db.sql # DDL completo + carga de dados
???
????????? src/
????????? app/
??? ????????? UMain # Tela principal (View)
????????? connection/
??? ????????? UConfigINI # Leitura do config.ini
??? ????????? UDM # DataModule com TFDConnection
????????? entities/
??? ????????? UEntityBase # Classe base das entidades
??? ????????? UCliente
??? ????????? UProduto
??? ????????? UPedido # Agrega TObjectList<TPedidoItem>
??? ????????? UPedidoItem # Auto-calcula VlrTotal nos setters
????????? repositories/
??? ????????? URepositoryBase # Base gen??rica com ObterPorCodigo/ValidarSeExiste
??? ????????? UClienteRepository
??? ????????? UProdutoRepository
??? ????????? UPedidoRepository # Inserir/Atualizar/Carregar/Excluir/Listar com transa????o
????????? services/
??? ????????? UClienteService
??? ????????? UProdutoService
??? ????????? UPedidoService # Valida????es e orquestra????o
????????? tests/
????????? UPedidoVendaTests # Testes unit??rios com DUnitXCriando o banco de dados
1. Criar o arquivo .fdb
Execute via isql, FlameRobin ou IBExpert, ajustando o caminho conforme seu ambiente:
CREATE DATABASE 'C:\Delphi-PedidoVenda\database.fdb'
USER 'SYSDBA' PASSWORD 'masterkey'
PAGE_SIZE = 4096
DEFAULT CHARACTER SET UTF8;Ou use o arquivo pronto:
database/create-database.sql2. Rodar o script DDL + carga
Com o banco criado, conecte nele e execute:
database/db.sqlO script cria:
- Sequences
SEQ_PEDIDOeSEQ_PEDIDO_ITEM - Tabelas
CLIENTE,PRODUTO,PEDIDO,PEDIDO_ITEM - Triggers de auto-incremento para
PEDIDO.NUMERO_PEDIDOePEDIDO_ITEM.NUMERO_ITEM - Índices e chaves estrangeiras
- 10 clientes e 10 produtos para teste
Atenção: execute os scripts na ordem indicada. O
db.sqlpressupõe que o banco já existe.
Configurando o INI
Copie o arquivo de exemplo e renomeie:
bin/config.ini.example ??? bin/config.iniEdite com os dados do seu ambiente:
[DATABASE]
Server=localhost
Port=3050
Database=C:\Delphi-PedidoVenda\database.fdb
Username=SYSDBA
Password=masterkey
ClientLibrary=.\fbclient.dll| Chave | Descrição |
|---|---|
Server |
IP ou hostname do servidor Firebird |
Port |
Porta TCP (padrão: 3050) |
Database |
Caminho completo do arquivo .fdb |
Username |
Usuário do banco |
Password |
Senha do usuário |
ClientLibrary |
Caminho para o fbclient.dll |
O
fbclient.dlldo Firebird 4.0 está incluído em/bin. Se preferir usar o instalado localmente, aponte paraC:\Program Files\Firebird\Firebird_4_0\fbclient.dll.
O
config.inideve estar na mesma pasta do executável.
Executando o projeto
Via Delphi IDE
- Abra o group project:
src/grpPedidoVenda.groupproj - Defina
PedidoVendacomo projeto ativo - Certifique-se de que o
config.iniestá no diretório de saída (ex:src/Win32/Debug/) - Compile e execute (
F9)
Via executável compilado
- Reúna em uma mesma pasta:
PedidoVenda.exe,fbclient.dlleconfig.ini - Execute o
PedidoVenda.exe
Roteiro de testes manuais
A tela é dividida em dois painéis: à esquerda a listagem de todos os pedidos com o total geral, à direita o formulário de pedido.
1. Listagem inicial
- Ao abrir a aplicação, o grid à esquerda exibe todos os pedidos gravados com número, cliente e valor total
- O rodapé do painel esquerdo exibe o Valor Total Geral (soma de todos os pedidos)
- Esperado: grid vazio se nenhum pedido foi gravado ainda
2. Cliente inválido
- No campo Cód. Cliente, informe um código inexistente (ex:
999) e pressione TAB - Esperado: mensagem "Cliente não encontrado", campos de cliente permanecem vazios
3. Novo pedido completo
- Clique em Novo Pedido
- Informe
1em Cód. Cliente e pressione TAB - Esperado: Nome, Cidade e UF preenchidos automaticamente (somente leitura)
- Informe
1em Cód. Produto e pressione TAB - Esperado: Descrição e Valor Unitário preenchidos automaticamente
- Informe
2em Quantidade e pressione TAB — o Valor Total do item é calculado automaticamente - Clique em Inserir/Atualizar Item
- Esperado: item inserido no grid de itens, total do pedido atualizado no rodapé
- Preencha o campo Observação com algum texto
- Clique em Gravar Pedido
- Esperado: mensagem de sucesso com o número do pedido gerado; grid de pedidos atualizado à esquerda — anote o número gerado
4. Produtos repetidos
- Com um pedido aberto, informe o mesmo código de produto duas vezes com quantidades diferentes
- Esperado: dois itens distintos no grid (linhas separadas), totais somados corretamente
5. Editar item via teclado (ENTER)
- Com itens no grid de itens, posicione o cursor sobre um item e pressione ENTER
- Esperado: campos de produto/quantidade/valor preenchidos para edição
- Altere a quantidade e clique em Inserir/Atualizar Item
- Esperado: linha atualizada no grid, total do pedido recalculado
O duplo clique no item também aciona a edição.
6. Excluir item via teclado (DEL)
- Com itens no grid de itens, selecione um item e pressione DEL
- Confirme a exclusão
- Esperado: item removido do grid e total do pedido recalculado imediatamente
7. Validações ao gravar
| Cenário | Esperado |
|---|---|
| Gravar sem informar cliente | Mensagem "Informe o cliente" |
| Gravar sem nenhum item | Mensagem "Pedido sem itens" |
| Gravar com valor total zero | Mensagem "Valor total inválido" |
8. Carregar pedido pela listagem
- No grid de pedidos à esquerda, selecione um pedido e clique em Carregar Pedido
- Esperado: cabeçalho, observação e itens do pedido carregados no formulário à direita
9. Editar pedido existente
- Carregue um pedido existente conforme o teste 8
- Altere a observação ou adicione um novo item
- Clique em Gravar Pedido
- Esperado: pedido atualizado, grid de pedidos à esquerda reflete o novo valor total
10. Cancelar pedido
- Com um pedido carregado no formulário, clique em Cancelar Pedido e confirme
- Esperado: mensagem de sucesso, formulário limpo, pedido removido do grid à esquerda
- Tente carregar o mesmo número novamente pelo campo de número
- Esperado: mensagem "Pedido não encontrado"
11. Total geral atualizado
- Grave dois pedidos com valores distintos
- Esperado: campo Valor Total Geral no rodapé do painel esquerdo reflete a soma correta
- Cancele um dos pedidos
- Esperado: total geral recalculado automaticamente após o cancelamento
Executando os testes unitários
- No Delphi IDE, defina
PedidoVendaTestscomo projeto ativo no group project - Compile e execute (
F9) - O runner do DUnitX exibe os resultados no console
Cobertura:
| Grupo | Casos |
|---|---|
| Item | Cálculo do total; recálculo ao alterar quantidade; recálculo ao alterar valor unitário; item com valor zero |
| Pedido | Total com múltiplos itens; recálculo após exclusão de item; produtos repetidos permitidos; total zero sem itens; 10 itens acumulados; valores fracionados |
Decisões técnicas relevantes
Listagem de pedidos com ListarPedidos
O TPedidoRepository.ListarPedidos busca os números dos pedidos ordenados por data e número decrescentes, e para cada um chama Carregar — que já faz o JOIN com CLIENTE e carrega os itens com JOIN em PRODUTO. Essa abordagem reutiliza o mapeamento completo já existente sem duplicar código. Para volumes maiores, uma query única com agregação seria mais performática, mas para o escopo do teste a clareza tem prioridade.
TRepositoryBase<T> com generics
Base genérica que centraliza ObterPorCodigo e ValidarSeExiste, evitando duplicação de código entre TClienteRepository e TProdutoRepository. O ValidarSeExiste reutiliza ObterPorCodigo intencionalmente — o custo é idêntico ao de um SELECT COUNT(1) para buscas por PK com retorno de 0 ou 1 linha, e elimina a necessidade de uma segunda query escrita manualmente.
TPedidoItem com self-calculation
Os setters de Quantidade e VlrUnitario recalculam VlrTotal automaticamente via RecalcularTotal, garantindo que a entidade nunca fique em estado inconsistente independentemente de quem a manipule.
Delete/insert dos itens no Atualizar Na operação de atualização do pedido, todos os itens existentes são excluídos e reinseridos dentro da mesma transação. Simplifica o controle de estado em tela sem abrir mão de atomicidade — em caso de falha, rollback garante consistência.
TConfigINI separado do DataModule
A leitura do config.ini foi isolada em TConfigINI retornando um TDatabaseConfig (record), separando a responsabilidade de configuração da de conexão. O TfDM consome o record e configura o TFDConnection dinamicamente — sem nenhuma credencial hardcoded no código ou no DFM.
Produtos repetidos Digitar um código de produto manualmente sempre insere uma nova linha no grid. A atualização de linha existente só ocorre quando o item foi carregado via ENTER (ou duplo clique) no grid. Comportamento documentado pois o requisito é ambíguo nesse ponto.
Tela de Pedido de Venda final


