# **Histórico**

<br>

Após a criação do financeiro e comercial, foi criado o módulo de Estoque, inicialmente a modelagem foi pensada na hierarquia e no item, porém percebeu-se a necessidade de cada vez mais incluir informações na hierarquia e não apenas no SKU, isso fez com que muitas informações estivessem preenchidas na hierarquia e também no SKU, fazendo com que o mesmo dado estivesse igual em mais de um local, dessa forma foi alterado para uma tabela de Itens auto relacionada.

<br>

## Hierarquia de Itens

<br>

Na estrutura de dados da tabela de Itens, existe uma hierarquia para ser seguida, onde o item "principal" de cada categoria, que dá origem aos demais itens, é chamado de *"Item Pai"* e a partir deste são criados os demais, sempre respeitando a nomenclatura do item pai da hierarquia do nível anterior.

Por exemplo como na imagem abaixo:

<br>

![Hierarquia Itens](estoque1.png)\

<br>

Nessa tabela de item auto relacionada, há varios itens, foi convencionada que o último item dessa relação é chamado de SKU, antes chamado de lote. Isto quer dizer que pode haver vários níveis hierárquicos no cadastro dos itens, até chegar ao SKU que é o item propriamente dito.

<br>
 
## Local de Armazenamento

<br>

No início havia tabelas relacionadas de tipos de itens, no entanto, para uma melhor modelagem do estoque do item no sistema, foi necessário criar uma tabela de **local de armazenamento**. Este cadastro de locais de armazenamento, carrega a qual filial pertence e o nome, ele serve para vincular o item com a conta de estoque.

O Item dentro do Local de Armazenamento, precisava ser representado de alguma forma, conceitualmente é como se houvesse uma tabela que fosse a união entre local de armazenamento e Item. Por exemplo, há a tabela de conta estoque, para representar essa união entre o local de armazenamento e o item, foi criado outro tipo de conta estoque, exemplo "caneca.deposito". Esta seria uma conta de estoque que indica o local de armazenamento a que pertence. Ou seja o Local de Armazenamento, possui o item e a conta de estoque.

Dessa forma, podemos entender que o Local de Armazenamento é representado por uma conta e o item também, pois existe uma união entre essas duas contas de estoque, essa união é criada apenas sob demanda, ou seja, apenas quando é necessário, no caso de transferências de estoque por exemplo.

No entanto, há diagramas conceituais, que fisicamente na implementação não foram criadas dessa forma, devido a quantidade de linhas que seria necessário, multiplicando itens por locais de armazenamento. Isto foi feito através de *"querys"* e *"views"* e quando necessário criar as linhas na tabela.

<br>

## Conta Estoque e Conta Saldo

<br>

No módulo Financeiro, existe a conta financeira que possui especialização conta corrente, da mesma forma ocorre a conta estoque, que armazena a movimentação dos itens no sistema.

No caso do estoque, foi criado uma tabela *"Conta Saldo"* está é apenas para guardar os saldos das contas de estoque, toda vez que ocorre uma movimentação no estoque, o saldo na data é armazenado nesta tabela, ela não guarda extratos, apenas o saldo.

A conta financeira é o vínculo com a conta saldo, quando é realizado um lançamento de estoque, um *"trigger"* cria uma linha de crédito/débito, no saldo da data no lançamento de estoque e caso em determinado dia não ocorra nenhuma movimentação, não terá nenhuma linha na tabela de saldo para este dia.

<br>

## Considerações Técnicas sobre a Conta Saldo

<br>

A conta saldo é uma das partes mais importantes no sistema e ela pode ser vista como frágil com relação a disponibilidade do Gestor como um todo. Pois podem ocorrer muitos problemas de conflito de transação, isso ocorre devido a conta saldo ter diversos *"updates"* em sequencia, pois diversas operações realizadas terminam em *"updates"* na conta saldo, dessa forma, ela é atualizada constantemente.

Isso pode aumentar as chances de ocorrer conflito de transação, devido ao comando *"update"* bloquear o registro e no banco de dados _Firebird_, o bloqueio só ocorre naquele registro no *"update"* e não tabela inteira, então aquele registro é bloqueado até que o comando *"commit"* seja finalizado. Dessa forma, caso ocorra algum outro *"update"* durante este processo, poderá dar erro pois aquele registro já está sendo utilizado.

Então neste sentido, a tabela conta saldo é frágil, pois se for realizado um *"update"* e a transação ficar aberta, diversas outras operações não irão funcionar.

O sistema aceita lançamentos com datas retroativas, cada vez que é feito um destes, a conta saldo atualiza o saldo do último lançamento.

É possível informar um saldo inicial no item, quando isto é feito, o sistema adiciona essa linha diretamente na conta estoque do item sem necessidade de realizar algum lançamento, na conta saldo ocorre um registro inicial, e a cada *"update"* irá recalcular os demais, isto pode causar travamentos ou lentidão no sistema, pois serão muitas linhas pendentes de atualização.

Problemas podem ocorrer pois foi implementado como *"update"*, a solução seria que isto fosse alterado para *"insert"*, devido ao *"update"* bloquear o registro e esperar uma ação de *"commit"* ou *"rollbak"*, ele é a melhor opção pois garante que a informação sempre estará certa. Porém quando há muita concorrência, esse bloqueio faz com que os demais usuários não consigam realizar *"updates"* na tebela.

A ideia seria ter uma tabela intermediaria, onde seriam feitos esses *"inserts"*, o *"update"* seria feito de forma assíncrona, externa, e seria preciso corrigir todas as *"querys"*, *"views"* e *"procedures"* que buscam o saldo para considerar o saldo da tabela mais os lançamentos que não foram processados.

<br>

## Diagrama

<br>

```mermaid
graph TD;
CONTA_FINANCEIRA[Conta Financeira]-->CONTA_ESTOQUE[Conta Estoque];
CONTA_ESTOQUE-->LOCAL_ARMAZENAMENTO[Local de Armazenamento];
CONTA_ESTOQUE--Tabela Auto Relacionada-->ITEM[Item];
LANCAMENTO_ESTOQUE[Lançamento Estoque]--Origem/Destino-->CONTA_ESTOQUE
CONTA_FINANCEIRA-->CONTA_SALDO[Conta Saldo];
```

<br>

### Diagrama Representação da União entre duas tabelas

<br>

```mermaid
graph TD;
LOCAL_ARMAZENAMENTO[Local de Armazenamento]-->C_E_1[Conta Estoque 1];
C_E_1-->CANECA_CONTA_ESTOQUE[CANECA.CONTA.ESTOQUE];
C_E_2[Conta Estoque 2]-->CANECA_CONTA_ESTOQUE;
C_E_2-->CANECA[Caneca];
```
