Skip to content
  • Categorias
  • Recente
  • Tags
  • Popular
  • Usuários
  • Grupos
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (Brite)
  • No Skin
Collapse

Automatize Fórum

  1. Home
  2. Wiki-Automatize
  3. Relatório de Saldos e Movimentação

Relatório de Saldos e Movimentação

Agendado Fixado Trancado Movido Wiki-Automatize
1 Posts 1 Posters 4 Visualizações 1 Watching
  • Mais Antigo para Mais Recente
  • Mais Recente para Mais Antigo
  • Mais Votados
Responder
  • Responder como tópico
Entre para responder
Este tópico foi deletado. Apenas usuários com privilégios de moderação de tópico podem vê-lo.
  • cassolC
    cassolC
    cassol
    Global Moderator
    escreveu última edição por cassol
    #1

    Introdução

    O objetivo desse manual é documentar tudo o que envolve o processo do cálculo mas de uma forma mais técnica, para facilitar os testes do suporte ou futuras correções de bugs pelo desenvolvimento.

    A forma como é calculado os Saldos e Movimentações dos produtos foi alterada. Anteriormente o relatório calculava toda a movimentação no momento da impressão, o que gerava lentidão quando o cliente possuía uma base de dados muito grande.

    A partir de agora os saldos serão calculados diariamente, evitando que o relatório tenha uma gama de dados grande para processar.

    Onde ficam armazenados os saldos?

    Os saldos e movimentações serão armazenados na tabela SaldosEstoque que contém num único registro todas as movimentações do produto no dia, como: saldo anterior, entradas, saídas, ajustes e vendas.

    Por exemplo:

    SELECT * FROM SaldosEstoque
    

    Resultado:

    idSaldosEstoque    salEmpresa    salProduto    salDataMovimento    salSaldoAnterior    
         38705             1            1059         27/12/2016           0,00    
    salEntradas    salSaidas    salAjusteMais    salAjusteMenos    salVendas
       300,00           0,00         0,00             0,00           0,00    
    

    A rotina que calcula os saldos e armazena na tabela SaldosEstoque é a sp dbo.spc_mov_processa_saldos_estoque.sql.

    Quem executa a rotina de cálculo?

    Quem executa a sp é o AutomatizeGO, através do plugin SaldoEstoque.dll.

    O processamento é feito a cada 1 hora e filtrará somente movimentos que foram alterados a mais de meia hora, isso para evitar rodar a rotina com o cliente ainda digitando um movimento.

    O resultado da execução do AutomatizeGO pode ser verificada no log do mesmo em: C:\Arquivos de Programas\Automatize\log\AutomatizeGO\.

    Exemplo:

    Caso o processamento ocorra com sucesso:

    28/11 14:39:13,807 [30] INFO AutomatizeGo.ServiceGo - Info plugin AutomatizeGo.Plugins.SaldoEstoque, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null:
    EXEC SALDO ESTOQUE
    

    Abaixo um exemplo caso ocorra um problema:

    28/11 14:04:26,034 [6] INFO AutomatizeGo.ServiceGo - Info plugin AutomatizeGo.Plugins.SaldoEstoque, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null:
    NÃO ENCONTRADO TABELA E SP DE PROCESSAMENTO DO SALDO
    

    Note que o erro foi "NÃO ENCONTRADO TABELA E...". Para esse erro ocorrer, uma das seguintes situações deve ter ocorrido:

    • A tabela SaldosEstoque não existir no banco;
    • A sp dbo.spc_mov_processa_saldos_estoque.sql não exista;
    • O campo MovimentoProdutoItem.mpiSaldoProcessado não exista (abaixo esse campo é explicado);
    • O campo MovimentoProdutoItemComposicao.mpcSaldoProcessado não exista (abaixo esse campo é explicado).

    Na primeira execução, caso a tabela SaldosEstoque esteja vazia, a sp irá recalcular toda a movimentação de todos os produtos e armazenar nela. Sendo assim, para fins de teste, caso haja a necessidade de se recalcular tudo novamente, basta apagar a tabela da seguinte forma:

    truncate table SaldosEstoque
    

    O procedimento pode demorar um pouco (em alguns testes com bases grandes, menos de 3 minutos) dependendo da quantidade de movimentos do cliente, então é necessário verificar o log do AutomatizeGO se a mensagem "EXEC SALDO ESTOQUE" foi apresentada ou algum outro erro.

    Em que momento serão calculados os saldos dos produtos?

    O saldo é calculado nas seguintes situações:

    • logo na primeira execução do plugin do AutomatizeGO ao ver que a tabela SaldosEstoque está vazia
    • Ao alterar a situação do movimento
    • Ao excluir um movimento
    • Ao incluir um produto no movimento
    • Ao alterar a quantidade de um produto dentro de um movimento
    • Ao excluir um produto do movimento

    Para permitir esses monitoramentos foram criados os seguintes gatilhos (triggers):

    • dbo.tu_MovimentoProduto.sql
      • é disparado quando houver alteração na situação do movimento.
        • um registro será criado na tabela temporária TmpSaldosEstoque para que o AutomatizeGO processe essa alteração.
    • dbo.td_MovimentoProduto.sql
      • é disparado quando houver exclusão do movimento
        • da mesma foram um registro será criado na tabela temporária TmpSaldosEstoque para que o AutomatizeGO processe essa exclusão.
    • dbo.tu_MovimentoProdutoItem.sq
      • é disparado ao alterar a quantidade de um produto dentro do movimento.
        • os campos MovimentoProdutoItem.mpiSaldoProcessado e MovimentoProdutoItemComposicao.mpcSaldoProcessado serão setados para 0 (zero), para que o AutomatizeGO processe a alteração
    • dbo.td_MovimentoProdutoItem.sql
      • é disparado excluir um produto do movimento.
        • um registro será criado na tabela temporária TmpSaldosEstoque para cada produto e cada composição, para que o AutomatizeGO processe essa alteração.

    Cliente possui centralização, como funciona?

    A rotina de cálculo irá rodar nas filiais e, na central caso essa esteja indicada no campo Node.NodeDest (abaixo).

    Após rodar a sp na filial os registros da tabela SaldosEstoque são enviados para a central para permitir visualizar nela o relatório de Saldos e Movimentação da filial.

    Nunca os dados serão enviados da central para as filiais ou de uma filial para outra.

    Não é possível visualizar o relatório de uma filial estando na outra. Por exemplo, a filial 1 não conseguirá ver da 2 e vice-versa. Na central será possível ver das duas filiais.

    Bom, se a rotina sempre vai rodar nas filiais, então em que situação ela rodará também na central?

    Para isso teremos que verificar a tabela Node na central.

    Exemplo de central que irá rodar:

    select * from node
    

    Resultado:

    KEY = corp       nodeDest = 4 
    

    Exemplo de central que não irá rodar:

    select * from node
    

    Resultado:

    KEY = corp       nodeDest = NULL
    

    Posso testar o cálculo sem que seja pelo AutomatizeGO?

    Sim, como o AutomatizeGO irá rodar o cálculo dos saldos a cada 1 hora, talvez seja conveniente utilizar o script abaixo.

    Não esqueça de trocar a filial no início do script, caso necessário:

    SET NOCOUNT ON
      
    DECLARE @idEmpresa  int
        
    set @idempresa = 1  -- << TROQUE A FILIAL AQUI >>
    
        
    -- se não tem registro na tabela então ja recalcula tudo pela primeira vez
    if NOT exists(select top 1 1 from SaldosEstoque)
    BEGIN
        print 'Primeiro recalculo'
        exec spc_mov_processa_saldos_estoque @idempresa=@idEmpresa, @dataInicial='01/01/2000'
    
        UPDATE MovimentoProdutoItem SET
            mpiSaldoProcessado = 1
        
        UPDATE MovimentoProdutoItemComposicao SET
            mpcSaldoProcessado = 1  
        RETURN
    END
    
    -- exclui os temporarios processados
    delete from TmpSaldosEstoque where saeProcessado = 1
    
    
    -- PROCURA pelos registros não processados do movimento para executar a spc_mov_processa_saldos_estoque
    DECLARE @curEmpresa int, @curProduto int, @curDt smalldatetime
            , @curIdMpi int, @curIdMpc int, @curProcessado bit, @curidTmpSaldos int
            , @msgerro varchar(2000)
    
    DECLARE @TBPROC TABLE  (
        idEmpresa int,
        prod int,
        dt datetime,
        idMpi int,
        idMpc int,
        sysInc datetime,
        processado bit,
        idTmpSaldos int
    )
        
    INSERT INTO @TBPROC (idEmpresa, prod, dt, idMpi, idMpc, sysInc, processado, idTmpSaldos)
        SELECT DISTINCT 
                idEmpresa = mvpEmpresa
            , prod = MPI.mpiProduto
            , Dt = CAST(FLOOR(CAST(MVP.mvpData AS FLOAT)) AS DATETIME) --retira a hora da data
            , IDMPI = idMovimentoProdutoItem
            , null 
            , isnull(mpi.sysRegistro, mpi.sysInc)
            , 0
            , null
        FROM MovimentoProdutoItem MPI
            INNER JOIN MovimentoProduto MVP ON MVP.idMovimentoProduto   = MPI.mpiMovimentoProduto 
        where MVP.mvpEmpresa = @idEmpresa
            and isnull(MPI.mpiSaldoProcessado,0) = 0
            and (IsNull(MVP.mvpSituacao, 0) in (0,9))
    
        UNION ALL
                
        -- composição
        SELECT DISTINCT 
                idEmpresa = mvpEmpresa
            , MPC.mpcProduto
            , Dt = CAST(FLOOR(CAST(MVP.mvpData AS FLOAT)) AS DATETIME) 
            , null
            , idMovimentoProdutoItemComposicao
            , isnull(mpi.sysRegistro, mpi.sysInc)
            , 0
            , null
        FROM MovimentoProdutoItemComposicao MPC
            INNER JOIN MovimentoProdutoItem MPI ON MPI.idMovimentoProdutoItem   = MPC.mpcMovimentoProdutoItem
            INNER JOIN MovimentoProduto     MVP ON MVP.idMovimentoProduto       = MPI.mpiMovimentoProduto 
    
        where MVP.mvpEmpresa = @idEmpresa
            and isnull(MPC.mpcSaldoProcessado,0) = 0
            and (IsNull(MVP.mvpSituacao, 0) in (0,9))
             
    
        UNION ALL 
    
        SELECT DISTINCT
              saeEmpresa
            , saeProduto
            , CAST(FLOOR(CAST(saeData AS FLOAT)) AS DATETIME)
            , null
            , null
            , sysInc
            , 0
            , idTmpSaldosEstoque
        FROM TmpSaldosEstoque
        WHERE saeProcessado = 0
          and saeEmpresa = @idEmpresa
    
    
        ORDER BY idEmpresa, prod, dt
    
    
    select * from @TBPROC
        
    
     -- DEFINE UM CURSOR DINAMICO PORQUE VOU ALTERAR OS DADOS DA COLUNA
     -- PROCESSADO E QUERO QUE REFLITA NOS PROCESSAMENTOS SEGUINTES
    DECLARE curMov CURSOR LOCAL DYNAMIC 
        FOR SELECT 
                idEmpresa ,
                prod ,
                dt ,
                processado 
            FROM @TBPROC
            --WHERE (sysInc is null or sysInc < dateadd(minute, -30, current_timestamp)) -- pega somente o que foi modificado a mais de 30min
    
    --
    -- ABRE O CURSOR E PERCORRE OS MOVIMENTOS
    --    
    OPEN curMov
    FETCH NEXT FROM curMov INTO @curEmpresa, @curProduto, @curDt, @curProcessado
                
    WHILE @@FETCH_STATUS = 0
    BEGIN
        --print 'Processa?: ' + cast( @curProduto as varchar) + ' | ' + convert(varchar(12), @curDt, 103) + ' > ' + CAST(@curProcessado as varchar)
        
        if @curProcessado = 0
        begin 
            --print 'Calculando...'
            begin try
                exec dbo.spc_mov_processa_saldos_estoque 
                      @idEmpresa    = @curEmpresa
                    , @DataInicial  = @curDt
                    , @DataFinal    = null
                    , @idProduto    = @curProduto
            end try
            begin catch
                SET @MSGErro = 'Erro processando salods: ' +
                                ERROR_MESSAGE()+' /L:' + cast(error_line() as varchar)
                RAISERROR(@MSGErro, 16, 1)
                GOTO SAIR
            end catch
    
            -- a spc_mov_processa_saldos_estoque processa todos os movimentos
            -- do produto a partir de uma data, então se existe mais algum 
            -- registro do produto com uma data superior a @curDt, vou marcar como processado
    
            UPDATE MovimentoProdutoItem SET
                mpiSaldoProcessado = 1
            WHERE IDMovimentoProdutoItem IN (
                SELECT idMpi
                FROM @TBProc
                WHERE idEmpresa = @curEmpresa
                  and prod = @curProduto
                  and dt >= @curDt
            )
    
            --composição
            UPDATE MovimentoProdutoItemComposicao SET
                mpcSaldoProcessado = 1
            WHERE idMovimentoProdutoItemComposicao IN (
                SELECT idMpc
                FROM @TBProc
                WHERE idEmpresa = @curEmpresa
                  and prod = @curProduto
                  and dt >= @curDt
            )     
    
            -- temporaria com os excluidos
            UPDATE TmpSaldosEstoque SET
                saeProcessado = 1
            WHERE idTmpSaldosEstoque IN (
                SELECT idTmpSaldos
                FROM @TBProc
                WHERE idEmpresa = @curEmpresa
                  and prod = @curProduto
                  and dt >= @curDt
            )     
    
    
            UPDATE @TBPROC SET
                processado = 1
            WHERE idEmpresa = @curEmpresa
                and prod = @curProduto
                and dt >= @curDt
        end
    
        FETCH NEXT FROM curMov INTO @curEmpresa, @curProduto, @curDt, @curProcessado
    END
    
    SAIR:
    CLOSE curMov
    DEALLOCATE curMov
    

    Considerações finais

    Qual versão do AutomatizeGO que possui o plugin SaldoEstoque.dll?

    A partir da 5.0.6.


    Migrado da wiki (saldos_e_movimentacoes). Última edição em 01/12/2017; autores: cassol.

    1 Resposta Última resposta
    0

    Hello! It looks like you're interested in this conversation, but you don't have an account yet.

    Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

    With your input, this post could be even better 💗

    Cadastrar Login
    Responder
    • Responder como tópico
    Entre para responder
    • Mais Antigo para Mais Recente
    • Mais Recente para Mais Antigo
    • Mais Votados


    • Login

    • Não tem uma conta? Cadastrar

    • Login or register to search.
    • Primeiro post
      Último post
    0
    • Categorias
    • Recente
    • Tags
    • Popular
    • Usuários
    • Grupos