V10 RecursosGuías
RecursosGuías
Guías
Años | List of Articles

¿Cómo obtener Stock y PCM actualmente utilizando instrucciones SQL?

Última modificación el 03/05/2024

Además de los avances tecnológicos, la versión 10 de ERP PRIMAVERA aporta algunos cambios estructurales importantes, como:

  • La separación de Logística y Tesorería en los distintos módulos;
  • Una reorganización completa del módulo de Inventario, incluyendo el registro de stock y el costing en la fecha.

En este artículo exploraremos, mediante algunos ejemplos, cómo obtener valores de stock en la fecha de inventario utilizando instrucciones SQL.

Para más información sobre la estructura de tablas de este módulo, le recomendamos que consulte el artículo.

Ejemplo 1: Stock por estado de stock y existencias

Los movimientos de stock se registran en la tabla INV_Movimentosy la correcta ordenación de los registros se realiza mediante los campos Data y NumRegisto. El campo Data indica cuándo se produce el movimiento, mientras que el campo NumRegisto es un campo secuencial de tipo Identity. También existe el campo DataIntegracao que almacena la fecha en la que se registra el movimiento.

Los valores de stock calculados se guardan en varios campos según su categoría, para lo cual existen las categorías Stock_ y Stocks_. La primera se refiere al valor de stock por estado, donde el valor calculado se basa en el estado del campo EstadoStock. Las columnas Existencias representan el valor calculado para todos los estados cuyo parámetro "Existencias" está marcado en la respectiva ficha, es decir, ignora todo el stock que se encuentran en estados virtuales, como las previsiones.

Además de las categorías, los campos tienen un sufijo ARM_ ARMLOT_ LOT_ LOC_ LOCLOT_, que indica si se trata de stock calculado por Almacén, Lote o Localización o una combinación de dos: Almacén y Lote o Localización y Lote. También hay columnas sin sufijo que representan el stock global, independientemente de las categorías anteriores.

Siempre que desee obtener el stock de una categoría concreta, deberá establecer su filtro y elegir la columna de stock correspondiente que desea obtener. Por ejemplo, si desea obtener el stock de existencias para el Almacén A1 y el Lote L01, deberá obtener el valor de la columna ExistenciasArmLot_Actual y colocarlo en la cláusula Where el Almacén y el Lote:

SELECT Artigo, Armazem, Lote 

FROM INV_Movimentos

WHERE Armazem = 'A1' AND Lote = 'L01'
Ejemplo de cómo obtener varios valores de stock para un estado de stock determinado:
--- Obter Stock ao ESTADO de STOCK ---
-- Stock global do estado DISP 
SELECT A.Artigo, STK.EstadoStock, STK.Stock_Actual
FROM Artigo A
OUTER APPLY
(
	SELECT TOP 1 M.* FROM INV_Movimentos M
	WHERE M.Artigo = A.Artigo 
	AND M.EstadoStock = 'DISP'
	AND M.Data <= '2019-01-01'
	ORDER BY M.Data DESC, M.NumRegisto DESC
) STK 

-- Stock do armazém A1 do estado DISP 
SELECT A.Artigo, STK.EstadoStock, STK.Armazem, STK.StockArm_Actual
FROM Artigo A
OUTER APPLY
(
	SELECT TOP 1 M.* FROM INV_Movimentos M
	WHERE M.Artigo = A.Artigo 
	AND M.EstadoStock = 'DISP' AND M.Armazem = 'A1'
	AND M.Data <= '2019-01-01'
	ORDER BY M.Data DESC, M.NumRegisto DESC
) STK 

-- Stock do armazém A1 e Lote L01 do estado DISP 
SELECT A.Artigo, STK.EstadoStock, STK.Armazem, STK.Lote, STK.StockArmLot_Actual
FROM Artigo A
OUTER APPLY
(
	SELECT TOP 1 M.* FROM INV_Movimentos M
	WHERE M.Artigo = A.Artigo 
	AND M.EstadoStock = 'DISP' AND M.Armazem = 'A1' AND Lote = 'L01'
	AND M.Data <= '2019-01-01'
	ORDER BY M.Data DESC, M.NumRegisto DESC
) STK 

-- Stock do armazém A1, Localização A1, Lote L01 do estado DISP 
SELECT A.Artigo, STK.EstadoStock, STK.Armazem, STK.Lote,STK.Localizacao, STK.StockLocLot_Actual
FROM Artigo A
OUTER APPLY
(
	SELECT TOP 1 M.* FROM INV_Movimentos M
	WHERE M.Artigo = A.Artigo 
	AND M.EstadoStock = 'DISP' AND M.Armazem = 'A1' AND Lote = 'L01' AND M.Localizacao = 'A1'
	AND M.Data <= '2019-01-01'
	ORDER BY M.Data DESC, M.NumRegisto DESC
) STK
Ejemplo de cómo obtener varios valores de existencias:
--- Obter Stock de existências de STOCK (todos os estados que contam para existências) ---
-- Stock global de existências
SELECT A.Artigo, STK.Existencias_Actual
FROM Artigo A
OUTER APPLY
(
	SELECT TOP 1 M.* FROM INV_Movimentos M
	WHERE M.Artigo = A.Artigo 
	AND M.Data <= '2019-01-01'
	ORDER BY M.Data DESC, M.NumRegisto DESC
) STK 

-- Stock do armazém A1 de existências
SELECT A.Artigo, STK.Armazem, STK.ExistenciasArm_Actual
FROM Artigo A
OUTER APPLY
(
	SELECT TOP 1 M.* FROM INV_Movimentos M
	WHERE M.Artigo = A.Artigo 
	AND M.Armazem = 'A1'
	AND M.Data <= '2019-01-01'
	ORDER BY M.Data DESC, M.NumRegisto DESC
) STK 

-- Stock do armazém A1 e Lote L01 de existências
SELECT A.Artigo, STK.Armazem, STK.Lote, STK.ExistenciasArmLot_Actual
FROM Artigo A
OUTER APPLY
(
	SELECT TOP 1 M.* FROM INV_Movimentos M
	WHERE M.Artigo = A.Artigo 
	AND M.Armazem = 'A1' AND Lote = 'L01'
	AND M.Data <= '2019-01-01'
	ORDER BY M.Data DESC, M.NumRegisto DESC
) STK 

-- Stock do armazém A1, Localização A1, Lote L01 de existências
SELECT A.Artigo, STK.Armazem, STK.Lote,STK.Localizacao,  STK.ExistenciasLocLot_Actual
FROM Artigo A
OUTER APPLY
(
	SELECT TOP 1 M.* FROM INV_Movimentos M
	WHERE M.Artigo = A.Artigo 
	AND M.Armazem = 'A1' AND Lote = 'L01' AND M.Localizacao = 'A1'
	AND M.Data <= '2019-01-01'
	ORDER BY M.Data DESC, M.NumRegisto DESC
) STK
Ejemplo de cómo obtener varios valores de existencias para el Grupo de Coste asociado al Almacén:
-- Stock do do Grupo de Custo GLOBAL 
SELECT A.Artigo, STK.GrupoCustos, STK.ExistenciasGrpCst_Actual
FROM Artigo A
OUTER APPLY
(
	SELECT TOP 1 M.*, Arm.GrupoCustos FROM INV_Movimentos M
	INNER JOIN Armazens Arm on Arm.Armazem = M.Armazem
	WHERE M.Artigo = A.Artigo 
	AND Arm.GrupoCustos = 'GLOBAL'
	AND M.Data <= '2019-01-01'
	ORDER BY M.Data DESC, M.NumRegisto DESC
) STK 

-- Stock do do Grupo de Custo GLOBAL e Lote L01 (Caso o Grupo de Custo tenha tratamento ao LOTE) 
SELECT A.Artigo, STK.GrupoCustos, STK.Lote, STK.ExistenciasGrpCstLot_Actual
FROM Artigo A
OUTER APPLY
(
	SELECT TOP 1 M.*, Arm.GrupoCustos FROM INV_Movimentos M
	INNER JOIN Armazens Arm on Arm.Armazem = M.Armazem
	WHERE M.Artigo = A.Artigo 
	AND Arm.GrupoCustos = 'GLOBAL' AND M.Lote = 'L01'
	AND M.Data <= '2019-01-01'
	ORDER BY M.Data DESC, M.NumRegisto DESC
) STK 

Ejemplo 2: Movimientos de costing

Los movimientos de costing se registran en la tabla INV_Custeio y, como en el ejemplo anterior, la correcta ordenación de los registros se realiza mediante los campos Data y NumRegisto. El campo Data indica cuándo se produce el movimiento, mientras que el campo NumRegisto es un campo secuencial de tipo Identity. También existe el campo DataIntegracao que almacena la fecha en la que se registra el movimiento.

Los valores de costing calculados se guardan en dos tipos de campos, en función de su categoría. Existen para eso los campos CustoGrpCst y CustoGrpCstLot. El primero permite obtener el coste del artículo de forma global para el grupo de costes, independientemente de si se trata de lotes. El segundo campo permite obtener el coste para el grupo de costes y Lote, pero solo se rellenará cuando el artículo y el grupo de costes traten lotes, es decir, cuando el campo Lote de la tabla tenga un valor diferente..

Ejemplo de cómo obtener el coste global y al lote:
--- Obter o custo para o Grupo de Custo GLOBAL 
SELECT A.Artigo,STK.GrupoCustos, STK.CustoGrpCstMBase_Actual
FROM Artigo A
OUTER APPLY
(
	SELECT TOP 1 M.* FROM INV_Custeio M
	WHERE M.Artigo = A.Artigo 
	AND M.GrupoCustos = 'GLOBAL'
	AND M.Data <= '2019-01-01'
	ORDER BY M.Data DESC, M.NumRegisto DESC
) STK 

--- Obter o custo para o Grupo de Custo GLOBAL e Lote L01
SELECT A.Artigo,STK.GrupoCustos, STK.Lote, STK.CustoGrpCstLotMBase_Actual
FROM Artigo A
OUTER APPLY
(
	SELECT TOP 1 M.* FROM INV_Custeio M
	WHERE M.Artigo = A.Artigo 
	AND M.GrupoCustos = 'GLOBAL' AND Lote = 'L01'
	AND M.Data <= '2019-01-01'
	ORDER BY M.Data DESC, M.NumRegisto DESC
) STK 


Ejemplo 3: Valor de inventario en la fecha

En los ejemplos anteriores, solo se han mostrado formas de obtener el stock o el costing de forma independiente. Sin embargo, a menudo querrá obtener el valor de inventario en una fecha determinada, que representa las existencias multiplicadas por el precio de coste medio en esa fecha.

Para obtener este valor por artículo, necesita relacionar las dos tablas, como se muestra en el siguiente ejemplo:

SELECT STK.Artigo,STK.GrupoCustos, STK.Lote, STK.Existencias, CUST.Custo, ValorInventario = STK.Existencias * CUST.Custo
FROM INV_GruposCustos G
OUTER APPLY
(
	SELECT TOP 1 M.Artigo, M.Lote, M.Data, Arm.GrupoCustos, Existencias = CASE WHEN A.TratamentoLotes = 1 AND G.ValorizacaoLote = 1 THEN M.ExistenciasGrpCstLot_Actual ELSE  M.ExistenciasGrpCst_Actual END
	FROM INV_Movimentos M
	INNER JOIN Artigo A ON A.Artigo = M.Artigo
	INNER JOIN Armazens Arm on Arm.Armazem = M.Armazem
	WHERE G.Grupo =  Arm.GrupoCustos
	AND M.Data <= '2019-01-01'
	ORDER BY M.Data DESC, M.NumRegisto DESC
) STK 
OUTER APPLY
(
	SELECT TOP 1 Custo = CASE WHEN M.Lote= '' THEN M.CustoGrpCstMBase_Actual ELSE M.CustoGrpCstLotMBase_Actual END 
	FROM INV_Custeio M
	INNER JOIN Artigo A ON A.Artigo = M.Artigo
	WHERE (M.Artigo = STK.Artigo AND M.GrupoCustos = STK.GrupoCustos AND ((M.Lote = STK.Lote AND G.ValorizacaoLote =1 ) OR G.ValorizacaoLote = 0))
	AND M.Data <= STK.Data
	ORDER BY M.Data DESC, M.NumRegisto DESC
) CUST
Bookmark or share this article
Esta página foi útil?
Obrigado pelo seu voto.

login para deixar a sua opinião.

Obrigado pelo seu feedback. Iremos analisá-lo para continuarmos a melhorar!