Como obter valores de inventário através de instruções SQL?
Além dos avanços tecnológicos , a versão 10 do ERP PRIMAVERA traz algumas mudanças estruturais importantes, tais como: Neste artigo vamos explorar, através de alguns exemplos, como obter valores de inventário recorrendo a instruções de SQL de forma a perceber melhor como estão estruturadas as tabelas. Os valores a obter referem-se a: Antes de mais, convém saber que todo e qualquer movimento que integre no módulo de Inventário tem, obrigatoriamente, que ser registado na tabela INV_Origens. Nesta tabela ficará registada toda a informação necessária referente à origem de cada movimento: Os movimentos de stock ficam registados na tabela INV_Movimentos, sendo que a correta ordenação dos registos faz-se pelos campos Data e NumRegisto. O campo Data indica quando ocorre o movimento, enquanto que o campo NumRegisto é um campo sequencial do tipo Identity. Existe ainda outro campo que guarda a data em que efetivamente o movimento é registado, o campo DataIntegracao. Exemplo da obtenção de um extrato de stocks para o artigo "A0001" de uma empresa DEMO: As quantidades atuais de stock podem ser agora obtidas a partir da tabela INV_ValoresActuaisStock, como mostrado neste exemplo: Os movimentos de custeio ficam registados na tabela INV_Custeio e, tal como no exemplo anterior, a correta ordenação dos registos faz-se pelos campos Data e NumRegisto. O campo Data indica quando ocorre o movimento, o campo NumRegisto é um campo sequencial do tipo Identity. Existe ainda outro campo que guarda a data em que efetivamente o movimento é registado, o campo DataIntegracao. Exemplo da obtenção de um extrato de custos para o artigo "A0001" de uma empresa DEMO: Os valores atuais de custeio podem ser agora obtidos a partir da tabela INV_ValoresActuaisCusteio, como mostrado neste exemplo: A qualquer movimento de saída de stock é aplicado uma valorização, sendo-lhe atribuído o valor de custo à data desse mesmo movimento (CMVMC). Esta valorização é aplicada a qualquer movimento de saída excetuando o movimento de saída de uma transferência para uma localização pertencente ao mesmo grupo de custos. O seguinte exemplo mostra a obtenção das valorizações para todos os movimentos de saída do artigo "A0001" numa empresa DEMO. Este exemplo junta outras tabelas, tais como a INV_Movimentos, que irá dar o próprio movimento de saída e a INV_Custeio, que relaciona a valorização com o movimento de custeio do qual é extraído o custo. As variações que ocorrem no custo médio têm de ser refletidas nas valorizações aplicadas aos documentos de saída. Estas valorizações, uma vez aplicadas, não voltam a ser alteradas, apenas são acrescentadas as variações, tanto positivas como negativas. Estas variações ficam registadas na tabela INV_Variacoes. O exemplo seguinte mostra como obter todas as variações aplicadas aos movimentos de saída do artigo "A0001".Exemplo 1: Movimentos de stock
/* Movimentos de stock (INV_Movimentos) */
SELECT orig.Documento, m.Data, m.DataIntegracao, m.NumRegisto, m.Artigo, m.Armazem, m.Localizacao, m.Lote, m.EstadoStock, m.TipoMovimento, orig.Transferencia
, m.Id, m.IdOrigem, orig.IdChave1, orig.IdChave2, orig.IdChave3
, orig.AplicaValorizacao
-- Quantidade movimentada (unidade base)
, Quantidade = FORMAT(m.Quantidade, '0.00')
-- Stock
, Stock_Anterior = FORMAT(m.Stock_Anterior, '0.00')
, Stock_Actual = FORMAT(m.Stock_Actual, '0.00')
, StockArm_Anterior = FORMAT(m.StockArm_Anterior, '0.00')
, StockArm_Actual = FORMAT(m.StockArm_Actual, '0.00')
, StockLoc_Anterior = FORMAT(m.StockLoc_Anterior, '0.00')
, StockLoc_Actual = FORMAT(m.StockLoc_Actual, '0.00')
, StockLot_Anterior = FORMAT(m.StockLot_Anterior, '0.00')
, StockLot_Actual = FORMAT(m.StockLot_Actual, '0.00')
, StockArmLot_Anterior = FORMAT(m.StockArmLot_Anterior, '0.00')
, StockArmLot_Actual = FORMAT(m.StockArmLot_Actual, '0.00')
, StockLocLot_Anterior = FORMAT(m.StockLocLot_Anterior, '0.00')
, StockLocLot_Actual = FORMAT(m.StockLocLot_Actual, '0.00')
-- Existência
, Existencias_Anterior = FORMAT(m.Existencias_Anterior, '0.00')
, Existencias_Actual = FORMAT(m.Existencias_Actual, '0.00')
, ExistenciasArm_Anterior = FORMAT(m.ExistenciasArm_Anterior, '0.00')
, ExistenciasArm_Actual = FORMAT(m.ExistenciasArm_Actual, '0.00')
, ExistenciasLoc_Anterior = FORMAT(m.ExistenciasLoc_Anterior, '0.00')
, ExistenciasLoc_Actual = FORMAT(m.ExistenciasLoc_Actual, '0.00')
, ExistenciasGrpCst_Anterior = FORMAT(m.ExistenciasGrpCst_Anterior, '0.00')
, ExistenciasGrpCst_Actual = FORMAT(m.ExistenciasGrpCst_Actual, '0.00')
, ExistenciasLot_Anterior = FORMAT(m.ExistenciasLot_Anterior, '0.00')
, ExistenciasLot_Actual = FORMAT(m.ExistenciasLot_Actual, '0.00')
, ExistenciasArmLot_Anterior = FORMAT(m.ExistenciasArmLot_Anterior, '0.00')
, ExistenciasArmLot_Actual = FORMAT(m.ExistenciasArmLot_Actual, '0.00')
, ExistenciasLocLot_Anterior = FORMAT(m.ExistenciasLocLot_Anterior, '0.00')
, ExistenciasLocLot_Actual = FORMAT(m.ExistenciasLocLot_Actual, '0.00')
, ExistenciasGrpCstLot_Anterior = FORMAT(m.ExistenciasGrpCstLot_Anterior, '0.00')
, ExistenciasGrpCstLot_Actual = FORMAT(m.ExistenciasGrpCstLot_Actual, '0.00')
FROM INV_Movimentos m WITH(NOLOCK)
INNER JOIN INV_Origens orig WITH(NOLOCK) ON m.IdOrigem = orig.Id
WHERE m.Artigo = 'A0001'
ORDER BY m.Data, m.NumRegisto
/* Quantidades atuais de stock (INV_ValoresActuaisStock) */
SELECT Artigo, Armazem, Localizacao, Lote, EstadoStock, DataStock
-- Stock actual na localização (unidade base)
, Stock = FORMAT(Stock, '0.00')
-- Identificador do último movimento que originou o stock atual
, IdMovimentoStock
-- Identificador do registo
, Id
FROM INV_ValoresActuaisStock WITH(NOLOCK)
WHERE Artigo = 'A0001'
ORDER BY Armazem, Localizacao, Lote
Exemplo 2 - Movimentos de custeio
/* Movimentos de custeio (INV_Custeio) */
SELECT TipoLancamento = case m.TipoLancamentoCusteio when 1 then 'ENC' when 2 then 'DES' when 3 then 'VPT' else 'Normal' end
, orig.Documento, m.Data, m.DataIntegracao, m.NumRegisto, m.Artigo, m.GrupoCustos, m.Lote, m.TipoMovimento, orig.Transferencia, m.TransferenciaValor
-- Quantidade movimentada
, Quantidade = FORMAT(m.Quantidade, '0.00')
-- Valores movimentados na moeda base
, ValorUnitarioMBase = FORMAT(m.ValorUnitarioMBase, '0.00')
, ValorAdicionalMBase = FORMAT(m.ValorAdicionalMBase, '0.00')
, ValorAbaterMBase = FORMAT(m.ValorAbaterMBase, '0.00')
-- Valores movimentados na moeda alternativa
, ValorUnitarioMAlt = FORMAT(m.ValorUnitarioMAlt, '0.00')
, ValorAdicionalMAlt = FORMAT(m.ValorAdicionalMAlt, '0.00')
, ValorAbaterMAlt = FORMAT(m.ValorAbaterMAlt, '0.00')
-- Valores de custeio na moeda base
, CustoGrpCstMBase_Anterior = FORMAT(m.CustoGrpCstMBase_Anterior, '0.00')
, CustoGrpCstMBase_Actual = FORMAT(m.CustoGrpCstMBase_Actual, '0.00')
, CustoGrpCstLotMBase_Anterior = FORMAT(m.CustoGrpCstLotMBase_Anterior, '0.00')
, CustoGrpCstLotMBase_Actual = FORMAT(m.CustoGrpCstLotMBase_Actual, '0.00')
-- Valores de custeio na moeda alternativa
, CustoGrpCstMAlt_Anterior = FORMAT(m.CustoGrpCstMAlt_Anterior, '0.00')
, CustoGrpCstMAlt_Actual = FORMAT(m.CustoGrpCstMAlt_Actual, '0.00')
, CustoGrpCstLotMAlt_Anterior = FORMAT(m.CustoGrpCstLotMAlt_Anterior, '0.00')
, CustoGrpCstLotMAlt_Actual = FORMAT(m.CustoGrpCstLotMAlt_Actual, '0.00')
-- Valores originais movimentados na moeda base
, ValorUnitarioOrigMBase = FORMAT(m.ValorUnitarioOrigMBase, '0.00')
, ValorAdicionalOrigMBase = FORMAT(m.ValorAdicionalOrigMBase, '0.00')
, ValorAbaterOrigMBase = FORMAT(m.ValorAbaterOrigMBase, '0.00')
-- Valores originais movimentados na moeda alteranativa
, ValorUnitarioOrigMAlt = FORMAT(m.ValorUnitarioOrigMAlt, '0.00')
, ValorAdicionalOrigMAlt = FORMAT(m.ValorAdicionalOrigMAlt, '0.00')
, ValorAbaterOrigMAlt = FORMAT(m.ValorAbaterOrigMAlt, '0.00')
-- Id's associados ao registo
, m.Id, m.IdMovimentoCusteioOrig, m.IdOrigem, m.IdMovimentoStock, m.IdValorizacao, orig.IdChave1, orig.IdChave2
-- Valores relacionados
, orig.AplicaValorizacao
, orig.ValorUnitario, orig.ValorAdicional, orig.ValorAbater
, orig.ActualizaPCU
FROM INV_Custeio m WITH(NOLOCK)
INNER JOIN INV_Origens orig WITH(NOLOCK) ON m.IdOrigem = orig.Id
WHERE m.Artigo = 'A0001'
ORDER BY m.Data, m.NumRegisto
/* Valores atuais de custeio (INV_ValoresActuaisCusteio) */
SELECT Artigo, GrupoCustos, Lote
-- Valores de custeio na moeda base
, CustoGrpCstMBase = FORMAT(CustoGrpCstMBase, '0.00')
, CustoGrpCstLotMBase = FORMAT(CustoGrpCstLotMBase, '0.00')
-- Valores de custeio na moeda alteranativa
, CustoGrpCstMAlt = FORMAT(CustoGrpCstMAlt, '0.00')
, CustoGrpCstLotMAlt = FORMAT(CustoGrpCstLotMAlt, '0.00')
-- Data do valor de custeio
, DataCusteio
FROM INV_ValoresActuaisCusteio WITH(NOLOCK)
WHERE Artigo = 'A0001'
ORDER BY DataCusteio
Exemplo 3: Valorização dos movimentos de saída
/* Valorizações dos movimentos de saída (INV_Valorizacoes) */
SELECT [Doc.] = orig.Documento, orig.Transferencia, v.Data, v.DataValor, v.Quantidade
-- Valor de custo na moeda base
, CustoMBase = FORMAT(v.CustoMBase, '0.00')
-- Valor de custo na moeda alternativa
, CustoMAlt = FORMAT(v.CustoMAlt, '0.00')
-- Grupo de custos
, GrupoCustos = c.GrupoCustos
-- Documento valorizado
, [Doc. Valor] = isnull(origc.Documento, '')
-- Identificador do movimento de saída de stock a ser valorizado
, v.IdMovimentoStock
-- Identificador do movimento de custeio a valorizar o movimento de saída
, v.IdMovimentoCusteio
-- Outros identificadores
, v.IdCustoPadrao, v.IdOrigem, v.Id
FROM INV_Valorizacoes v WITH(NOLOCK)
INNER JOIN INV_Origens orig WITH(NOLOCK) ON v.IdOrigem = orig.Id
INNER JOIN INV_Movimentos m WITH(NOLOCK) ON v.IdMovimentoStock = m.id
LEFT JOIN INV_Custeio c WITH(NOLOCK) ON v.IdMovimentoCusteio = c.Id
LEFT JOIN INV_Origens origc WITH(NOLOCK) ON c.IdOrigem = origc.id
WHERE m.Artigo = 'A0001'
ORDER BY v.Data, m.NumRegisto
Exemplo 4: Variações de custeio associadas às valorizações
/* Variações de custeio associadas às valorizações (INV_Variacoes) */
SELECT -- Documento, data e grupo de custos de referência
[Doc.Ref.] = origref.Documento, r.DataRef, GrupoCustosRef = cstref.GrupoCustos
-- Documento, data e grupo de custos da variação
, [Doc.Var.] = origvar.Documento, r.DataVariacao
-- Documento, data e grupo de custos da valorização
, [Doc.Val.] = origval.Documento, DataValorizacao = val.Data, GrupoCustosVal = cstvar.GrupoCustos
-- Valor da variação na moeda base
, ValorMBase = FORMAT(r.ValorMBase, '0.00')
-- Valor da variação na moeda alternativa
, ValorMAlt = FORMAT(r.ValorMAlt, '0.00')
-- Identificador do movimento de custeio de referência (ex: VFA)
, r.IdCusteioRef
-- Identificador do movimento de custeio que provoca a variação (ex: VPT/ENC/DES)
, r.IdCusteioVariacao
-- Identificador da valorização
, r.IdValorizacao
, r.Id
FROM INV_Variacoes r WITH(NOLOCK)
INNER JOIN INV_Custeio cstref WITH(NOLOCK) ON r.IdCusteioRef = cstref.Id
INNER JOIN INV_Origens origref WITH(NOLOCK) ON cstref.IdOrigem = origref.Id
INNER JOIN INV_Custeio cstvar WITH(NOLOCK) ON r.IdCusteioVariacao = cstvar.Id
INNER JOIN INV_Origens origvar WITH(NOLOCK) ON cstvar.IdOrigem = origvar.Id
LEFT JOIN INV_Valorizacoes val WITH(NOLOCK) ON r.IdValorizacao = val.Id
LEFT JOIN INV_Movimentos movval WITH(NOLOCK) ON val.IdMovimentoStock = movval.Id
INNER JOIN INV_Origens origval WITH(NOLOCK) ON val.IdOrigem = origval.Id
WHERE cstref.Artigo = 'A0001'
ORDER BY r.DataVariacao, val.Data
login para deixar a sua opinião.