♥ 0 | Não é possível concluir os processos de inventariação efetuados para o mês X. Aparece o erro “erro ao realizar a operação selecionada”. Marked as spam |
Private answer Foram detetadas várias discrepâncias nos artigos relacionadas com as unidades em stock VS números de série em stock. Estas são provocadas por movimentos provenientes da V9 em que o sistema era permissivo, ao contrário da V10. Uma vez que o inventário utiliza os números de série em stock é necessário que os números de série estejam corretos no momento da criação do inventário. Para corrigir os valores dos números de série dos artigos em questão poderá ser executada a script abaixo. Ultrapassada a questão dos inventários, resta validar os artigos que permanecem, com stock diferente dos números de série. Deixo abaixo uma query para validar as situações, sendo que a maioria dos casos se verifica em artigos que tem mais números de série do que stock. Neste caso poderão ser marcados os números de série daquele artigo/armazém como não estando em stock. Neste cas poderemos facultar uma query corretiva para acertar estes valores mediante o que se pretende:
----------- Validação Stock VS Números de Série em Stock ------------- SELECT iv.Artigo ,iv.Stock, TotalNS = NS.Total, * FROM INV_ValoresActuaisStock iv LEFT JOIN ( SELECT Total = COUNT(*), Artigo, Armazem, Localizacao, Lote FROM INV_NumerosSerie NS WHERE NS.Stock = 1 GROUP BY Artigo, Armazem, Localizacao, Lote ) NS ON NS.Artigo = iv.Artigo and NS.Armazem = iv.Armazem and iv.Localizacao = NS.Localizacao AND iv.Lote = NS.Lote INNER JOIN Artigo a on a.Artigo = iv.Artigo and a.TratamentoSeries = 1 WHERE ISNULL(NS.Total,0)<> ISNULL(iv.Stock,0) and ISNULL(iv.Stock,0) <> 0 order by 1
---- Movimentos de um determinado NS --- SELECT im.Id , im.Artigo, im.NumeroSerie, im.Stock, TotalMovs= StockNS.Stock, M.TipoMovimento, o.Documento, m.Data, M.* FROM INV_NumerosSerie im INNER JOIN INV_NumerosSerieMovimento inm On inm.IdNumeroSerie = im.Id INNER JOIN INV_Movimentos M On M.Id = inm.IdMovimentoStock INNER JOIN INV_Origens o On o.Id = M.IdOrigem LEFT JOIN ( SELECT im.Id, Stock = SUM (CASE WHEN m.TipoMovimento = 'S' THEN -1 ELSE 1 END) FROM INV_NumerosSerie im INNER JOIN INV_NumerosSerieMovimento inm On inm.IdNumeroSerie = im.Id INNER JOIN INV_Movimentos M On M.Id = inm.IdMovimentoStock GROUP BY im.Id ) StockNS ON StockNS.Id = im.Id WHERE 1=1 --im.Artigo = 'R355-10-1020' and im.Stock <> ISNULL(StockNS.Stock,0) --and im.Stock = 0 AND ISNULL(StockNS.Stock,0) = 1 --and o.Chave1 = 'ESI' order by im.Artigo, im.NumeroSerie, M.Data, M.NumRegisto
Para corrigir inconsistências com números de série: /* 5 - Números de série
*/
--- Colocar o stock a 1 em artigos que o somatório dá 1 -- update im set im.Stock = 1 FROM INV_NumerosSerie im LEFT JOIN ( SELECT im.Id, Stock = SUM (CASE WHEN m.TipoMovimento = 'S' THEN -1 ELSE 1 END) FROM INV_NumerosSerie im INNER JOIN INV_NumerosSerieMovimento inm On inm.IdNumeroSerie = im.Id INNER JOIN INV_Movimentos M On M.Id = inm.IdMovimentoStock GROUP BY im.Id ) StockNS ON StockNS.Id = im.Id WHERE 1=1 --AND im.Artigo = '010-19-0060' and im.Stock <> ISNULL(StockNS.Stock,0) AND im.Stock = 0 AND ISNULL(StockNS.Stock,0) = 1 --- Coloca o stock a zero em artigos que o somatório dá zero -- update im set im.Stock = 0 FROM INV_NumerosSerie im LEFT JOIN ( SELECT im.Id, Stock = SUM (CASE WHEN m.TipoMovimento = 'S' THEN -1 ELSE 1 END) FROM INV_NumerosSerie im INNER JOIN INV_NumerosSerieMovimento inm On inm.IdNumeroSerie = im.Id INNER JOIN INV_Movimentos M On M.Id = inm.IdMovimentoStock GROUP BY im.Id ) StockNS ON StockNS.Id = im.Id WHERE 1=1 --AND im.Artigo = '010-19-0060' and im.Stock <> ISNULL(StockNS.Stock,0) AND im.Stock = 1 AND ISNULL(StockNS.Stock,0) = 0 Se mesmo assim o problema exposto persistir numa base de dados clone pode-se ainda executar a seguinte script para resolver diferenças entre Stock de Artigo e Quantidade de Números de Série: /* 1º - Correr o recalculo de Stock Completo */ exec dbo.std_droptemptable '#tempregistoscalcstock' Go select product = im.artigo , [data] = min(im.[data]) , lot = im.lote , [location] = im.localizacao , warehouse = im.armazem , stockstate = im.estadostock , lastmovement = 0 , ruturastocks = cast(0 as tinyint) , a.tratamentolotes into #tempregistoscalcstock from inv_movimentos im inner join INV_Origens o on o.Id = im.IdOrigem inner join Artigo a on a.Artigo = im.Artigo group by im.artigo , im.armazem , im.localizacao , im.lote , im.estadostock , a.tratamentolotes exec inv_actualizastockbulk 1, '' GO /* 2º - Recalcular o Stock dos Números de Série */ ;WITH M AS ( SELECT IdNumSerie = NM.IdNumeroSerie, NumeroSerie = NM.NumeroSerie, IdMovStock = M.[Id],M.Armazem,M.Localizacao,M.Lote,M.EstadoStock,M.Data,M.TipoMovimento , RowNumb = ROW_NUMBER() OVER (PARTITION BY NM.IdNumeroSerie ORDER By M.[Data] DESC, M.NumRegisto DESC) , Stock = SUM(Case When M.TipoMovimento = 'S' Then -1 Else 1 END) OVER (PARTITION BY NM.IdNumeroSerie ORDER By M.[Data], M.NumRegisto) FROM INV_Movimentos M WITH(NOLOCK) INNER JOIN INV_NumerosSerieMovimento NM WITH(NOLOCK) ON NM.IdMovimentoStock = M.Id ) UPDATE ns SET Armazem = M.Armazem , Localizacao = M.Localizacao , Lote = M.Lote , EstadoStock = M.EstadoStock , DataStock = M.Data , NumeroSerie = M.NumeroSerie , Stock = CASE WHEN M.TipoMovimento = 'S' OR M.Stock<=0 THEN 0 ELSE 1 END FROM INV_NumerosSerie ns WITH(NOLOCK) INNER JOIN M ON M.IdNumSerie = ns.Id WHERE M.RowNumb = 1 /*
3º - Criar a tabela temporária com as diferenças */ EXEC dbo.STD_DropTempTable '#tmpNSStockInicial'
----------- Validação Stock VS Números de Série em Stock ------------- SELECT iv.Stock , iv.Artigo , iv.Armazem , iv.Localizacao , iv.Lote , iv.EstadoStock , TotalNS = ISNULL(NS.Total, 0) , DIF = iv.Stock - ISNULL(NS.Total, 0) INTO #tmpNSStockInicial FROM INV_ValoresActuaisStock IV LEFT JOIN ( SELECT Total = COUNT(*) , Artigo , Armazem , Localizacao , Lote , EstadoStock FROM INV_NumerosSerie NS WHERE NS.Stock = 1 GROUP BY Artigo , Armazem , Localizacao , Lote , EstadoStock ) NS ON NS.Artigo = iv.Artigo AND NS.Armazem = iv.Armazem AND iv.Localizacao = NS.Localizacao AND iv.Lote = NS.Lote AND iv.EstadoStock = NS.EstadoStock INNER JOIN Artigo A ON a.Artigo = iv.Artigo AND a.TratamentoSeries = 1 WHERE ISNULL(NS.Total,0) <> ISNULL(iv.Stock,0) ORDER BY 1 /*
4º - Adicionar números de série automáticos para colmatar falhas dos números de série em relação ao stock */ DECLARE @vArtigoAct NVARCHAR(48) , @vArmazemAct NVARCHAR(5) , @vLocalizacaoAct NVARCHAR(30) , @vLoteAct NVARCHAR(20) , @vEstadoAct NVARCHAR(10) , @vDiff INT , @SQL NVARCHAR(MAX) DECLARE Cursor_Registos CURSOR LOCAL FORWARD_ONLY STATIC READ_ONLY FOR SELECT Artigo, Armazem, Localizacao, Lote, EstadoStock, Dif FROM #tmpNSStockInicial WHERE DIF > 0 OPEN Cursor_Registos FETCH NEXT FROM Cursor_Registos INTO @vArtigoAct, @vArmazemAct, @vLocalizacaoAct, @vLoteAct, @vEstadoAct, @vDiff WHILE @@FETCH_STATUS = 0 BEGIN DECLARE @intI AS INT SET @intI = 1 WHILE @intI <= @vDiff BEGIN SET @SQL = 'INSERT INTO INV_NumerosSerie (ID, Artigo, Armazem, Localizacao, Lote, EstadoStock, NumeroSerie, DataStock, Stock, Documento) VALUES (NEWID(),'''+ @vArtigoAct +''','''+ @vArmazemAct +''','''+ @vLocalizacaoAct +''','''+ @vLoteAct +''','''+ @vEstadoAct +''',''SNAUTO.'+ CONVERT(NVARCHAR(20), @intI) +''',DATEADD(year, -1, GETDATE()),1,''SNAUTO.'+ CONVERT(NVARCHAR(20), @intI) +''')' EXEC(@SQL) SET @intI = @intI + 1 END FETCH NEXT FROM Cursor_Registos INTO @vArtigoAct, @vArmazemAct, @vLocalizacaoAct, @vLoteAct, @vEstadoAct, @vDiff END GO /*
5º - Para cada registo da tabela abaixo será necessário realizar os passos abaixo
*/ SELECT Artigo, Armazem, Localizacao, Lote, EstadoStock, Stock as StockArtigo, TotalNS as StockNS, Dif , ComandoUpdate='Update INV_NumerosSerie Set Stock=0 Where Artigo=''' + Artigo + ''' AND Armazem=''' + Armazem + ''' AND Localizacao=''' + Localizacao + ''' AND Lote=''' + Lote + ''' AND EstadoStock=''' + EstadoStock + '''' FROM #tmpNSStockInicial Where Dif<0 Order by Artigo, Armazem, Localizacao, Lote, EstadoStock Marked as spam | |
Private answer Tenho um cliente com inconsistências com Num de Séries Tentei executar as queries mas no ponto 4º - Adicionar números de série automáticos para colmatar falhas dos números de série em relação ao stock dá-me erro porque nao encontra a tabela '#tmpNSStockInicial' supostamente criada no ponto 3º
Continuo com erro ao fechar o Inventário, porque ao fechar vai ler que tem Stock 3, quando não tem, tem zero. E na tabela INV_Numerosserie já coloquei o campo Stock a False, mas mesmo assim está a contabilizar 3 numeros de série.
Marked as spam |