Estou projetando um banco de dados para nossa equipe de vendas usar como uma ferramenta de cotação rápida de tarefas. Gostaria de receber algum feedback sobre um aspecto específico do design.
Uma cotação é basicamente criada selecionando uma lista de 'assemblies' predefinidos, cada um com um preço acordado. Uma visão simplificada do formulário principal se parece com isso:
+------------ --- ---+
| Assembly options |
+------------+------------+----------+------------+---+---+---+ --- +--+
| assembly ▼ | unit cost | quantity | total cost | 1 | 2 | 3 | |50|
+------------+------------+----------+------------+---+---+---+ --- +--+
| VSD55 | £10'000 | 2 | £25'500 | 1 | 1 | | | |
| RDOL2.2 | £2'000 | 1 | £1'500 | | 1 | | | |
| DOL5.0 | £1'000 | 1 | £1'200 | | | 1 | | |
+------------+------------+----------+------------+---+---+---+ --- +--+
O usuário seleciona uma montagem predefinida, insere a quantidade e seleciona quaisquer 'opções' necessárias. Cada montagem possui potencialmente até 50 opções disponíveis. Uma opção também é uma montagem predefinida (submontagem) com seu próprio preço. O 'custo total' para cada linha é calculado como (custo da montagem principal * quantidade) + custo de qualquer opção.
Quando o usuário move o cursor para uma caixa de opção, o nome e o preço dessa opção são divulgados a ele.
Agora é aqui que fica complicado. Cada montagem possui sua própria lista de opções disponíveis. ou seja, a opção 1 para um 'VSD55' representa um subconjunto diferente da opção 1 para um DOL5.0.
Quanto às montagens aqui, estão as tabelas simplificadas que estou usando:
+-----------------+ +------------------------+ +-----------------------------+
| assembly | | assembly_option | | assembly_option_link |
+-----------------+ +------------------------+ +-----------------------------+
| assembly_id (PK)| | assembly_option_id (PK)| | assembly_option_link_id (PK)|
| assembly_name | | assembly_option_name | | assembly_id (FK) |
| unit_cost | | option_number | | assembly_option_id (FK) |
+-----------------+ | unit_cost | +-----------------------------+
+------------------------+
A tabela 'assembly_option_link' basicamente define quais opções estão disponíveis para cada montagem.
Agora, para as tabelas 'quote':
+-----------------+ +------------------------+
| quote | | quote_assembly |
+-----------------+ +------------------------+
| quote_id (PK) | | quote_assembly_id (PK) |
| quote_name | | assembly_id (FK) |
+-----------------+ | quantity |
+------------------------+
Agora, a parte complicada é como armazenar as opções selecionadas. Devo expandir a tabela 'quote_assembly' com todos os 50 campos de opção, mesmo que isso quebre as regras de normalização. Uma montagem nunca será selecionada com todas as 50 opções, portanto isso também parece muito ineficiente. No lado positivo, esta solução permite que o formulário de entrada do usuário seja mapeado diretamente para a tabela, facilitando a codificação.
A solução 'normalizada' eu acho que seria criar outra tabela como esta:
+------------------------------+
| quote_assembly_option |
+------------------------------+
| quote_assembly_option_id (PK)|
| quote_assembly_id (FK) |
| assembly_option_id (FK) |
| quantity |
+------------------------------+
Esta solução significa que apenas as opções selecionadas são armazenadas. Além disso, em vez de armazenar o número da opção, posso armazenar o 'assembly_option_id' real. Isso torna o cálculo do custo total da cotação mais simples, pois não preciso converter entre 'option_number' e 'assembly_option_id' para procurar o custo da opção de montagem. A principal desvantagem desta solução é que ela não se encaixa bem no formulário de entrada do usuário. Acho que vou precisar aplicar alguma codificação sofisticada para fazer a interface do formulário com as tabelas.
Alguém pode oferecer algum conselho de design aqui, por favor? Espero ter me explicado bem o suficiente.
MAIS INFORMAÇÕES
Também é um relatório de cotação detalhado que expande todas as opções selecionadas como itens de linha separados na montagem principal. Por exemplo:
+---------------------------------+------------+----------+------------+
| assembly | unit cost | quantity | total cost |
+---------------------------------+------------+----------+------------+
| VSD55 | £10'000 | 2 | £20'000 |
| - Seal leak protection | £ 5'000 | 1 | £ 5'000 | <-option 1
| - Motor over temp protection | £ 500 | 1 | £ 500 | <-option 2
+---------------------------------+------------+----------+------------+
| | | | £25'500 |
+---------------------------------+------------+----------+------------+