miércoles, 22 de junio de 2022

Gestión - Tablas Query Manager, Búsquedas formateadas, Modelos de Autorización y Reportes/Layouts Crystal Report

Les comparto en esta publicación las 4 tablas generalmente más demandadas en los procesos de las compañías (ojo no en todas) que debería correr cualquier consultor que este migrando SAP B1 SQL a HANA, para de esta manera saber a lo que se está enfrentando en una o más bases de datos:
  1. Query Manager
  2. Busquedas Formateadas
  3. Modelos de Autorización
  4. Reportes y Layouts Crystal Report
Las siguientes consultas son el script básico, pueden adornarlas como a ustedes mejor les convenga:

Query Manager
select T0."CatName", T1."QName"  from OQCN T0
inner join OUQR T1 on T0."CategoryId" = T1."QCategory"
where CatName not in ('SAP_DASHBOARD_002_DAB012_QUERY','Sistema','KPI_MOBILE_HANA','KPI_MOBILE')
and CatName not like ('SAP_DASHBOARD_%')
Order by T0."CatName"
 
Busquedas formateadas
Select CASE FormID when 133 then 'Factura Deudores' 
when 134 then  'Socio de Negocios'
when 804 then 'Catalogo de cuentas'
when 179 then 'Nota de Crédito' 
end FORM, ItemID,  QName
from CSHS a
inner join OUQR b on a.QueryId = b.IntrnalKey
 
Reportes y Layouts Crystal Report
select DocCode, DocName from RDOC
where Author not in ('System')
and TypeCode = 'RCRI'
 
Modelos de autorización
select a.Name 'Nombre Modelo', a.Remarks 'Descripción Modelo', c.Name as 'Nombre Etapa' , c.Remarks as 'Descripción Etapa'
,  e.U_NAME as  'Autorizador', c.MaxReqr as 'Autorizaciones requeridas', c.MaxRejReqr as 'Rechazos requeridos'
from OWTM a
inner join WTM2 b on a.WtmCode = b.WtmCode
inner join OWST c on b.WstCode = c.WstCode
inner join WST1 d on c.WstCode = d.WstCode
inner join OUSR e on d.UserID = e.USERID
where a.Active = 'Y'
order by [Nombre Modelo] , Autorizador,
[Nombre Modelo] , Autorizador 

¡Saludos!

sábado, 23 de octubre de 2021

Facturar solo lo que solicita la Orden de Venta

Les dejo un TN que es de mucha ayuda para evitar problemas con los clientes, reclamaciones por cobros de más y por envío de mercancía de más de lo que el cliente originalmente pide.

Ante una problemática en la actual empresa donde laboro me di a la tarea para bloquear la facturación que excede la cantidad de la orden de venta (Pedido Cliente).

Espero les ayude tanto como a nosotros en la compañía,

IF @object_type = '13' And @transaction_type  in ('A', 'U')
BEGIN
select @Quantity  =  convert(varchar, cast([Cdad a Facturar] as decimal(18,2))) ,  @quantiyOpen  = convert(varchar, cast([Cdad Pedida]  as decimal(18,2))) 
, @itemCode  = ItemCode from (
select t0.DocNum as [Pedido], T1.Quantity as [Cdad Pedida], t1.ItemCode /*, t3.DocNum as [Factura]*/, sum(T2.Quantity) as [Cdad a Facturar] 
from ORDR T0
inner join RDR1 T1 on T0.DocEntry = T1.DocEntry
inner join INV1 T2 on T0.DocEntry = t2.BaseEntry and t1.ItemCode = t2.ItemCode and T1.LineNum = t2.BaseLine and t2.BaseEntry = t1.DocEntry
inner join OINV T3 on T2.DocEntry = t3.DocEntry 
and t0.DocEntry = (select top 1 BaseEntry from INV1 where DocEntry = @list_of_cols_val_tab_del)
and t3.CANCELED = 'N'
group by t0.DocNum, t1.ItemCode, t1.LineNum,  T1.Quantity) Tabla
where [Cdad Pedida] < [Cdad a Facturar]
;
 IF EXISTS 
(select Pedido from (
select t0.DocNum as [Pedido], T1.Quantity as [Cdad Pedida] /*, t3.DocNum as [Factura]*/, sum(T2.Quantity) as [Cdad a Facturar] 
from ORDR T0
inner join RDR1 T1 on T0.DocEntry = T1.DocEntry
inner join INV1 T2 on T0.DocEntry = t2.BaseEntry and t1.ItemCode = t2.ItemCode and T1.LineNum = t2.BaseLine and t2.BaseEntry = t1.DocEntry
inner join OINV T3 on T2.DocEntry = t3.DocEntry 
and t0.DocEntry = (select top 1 BaseEntry from INV1 where DocEntry = @list_of_cols_val_tab_del)
and t3.CANCELED = 'N'
group by t0.DocNum, t1.ItemCode, t1.LineNum, T1.Quantity) Tabla
where [Cdad Pedida] < [Cdad a Facturar]
 )
 BEGIN 
  set @error = 1300001
  set @error_message = 'No se puede facturar por una cantidad mayor a la del pedido, Cdad Pedida: ' + @quantiyOpen + ' - Cdad a facturar: ' + @Quantity + ' - Artículo: ' + @itemCode + '.'
 END
END

miércoles, 22 de septiembre de 2021

Item cost not found for one or more items

 Esta vez les comparto un error que se nos presenta cuando intentamos realizar movimientos de inventario en el sistema o vía Data Transfer: Item cost not found for one or more items.

Para resolver tendríamos que activar la casilla en Detalles de Sociedad: Permitir liberación de stoc&k sin costos de artículos, como se aprecia en la imagen abajo.




Pero está no siempre es la opción ideal ya que se pierde el control de los artículos que no tienen costo en nuestro sistema, por lo que la segunda opción es asignarle un costo al artículo desde la revalorización de inventario que encuentras en el modulo de inventarios. En la imagen abajo muestro la ruta:


Una vez aplicado el costo, el artículo podrá tener movimientos de inventario.





martes, 21 de septiembre de 2021

Inventarios - Obtener el costo de artículo por Almacén en SAP

Hola de nuevo,

Les comparto como pueden obtener el costo de los artículos por almacén, esto nos ayuda bastante a la hora de detectar cuales no tienen costo, SAP en algunas de sus transacciones no no los permite según este configurado el sistema, como sabemos para darle un costo debemos usar la Revaloración de Inventario en el modulo de Inventarios.

SELECT distinct d.itemcode, c.ItemName, d.AvgPrice , d.WhsCode
from OITM c
inner join OITW d on c.ItemCode = d.ItemCode 
where d.WhsCode = 'CEDIS'

Espero les sirva. 

Validación de lote duplicado - TN en entrada de inventario

 Hola, les compartiré ahora un ejemplo para validar si la entrada que estamos realizando con lotes lleva uno que ya se halla ingresado con anterioridad, este ejemplo puede implementarse según el tipo de objeto donde se este ingresando o moviendo el lote.

Para el caso de entrada de mercancía por el modulo de inventario cree el siguiente ejemplo dada mi necesidad:

IF @object_type ='59' and @transaction_type in ('A')
BEGIN
declare @countRegistrados int
set @countRegistrados = (SELECT COUNT(c.batchnum) FROM IBT1 c
 inner join IBT1 B2 on c.BatchNum = B2.BatchNum and c.BatchNum in (isnull(b2.BatchNum,'')) and b2.BaseType = 59 and c.BaseType = 59 and c.BaseType = c.BaseType
 where  c.BaseEntry = @list_of_cols_val_tab_del
 and b2.BaseEntry <> @list_of_cols_val_tab_del)
 
if @countRegistrados > 0
begin
set @error = 1
set @error_message = 'Error TI... El lote ya existe, existe(n) ' + cast(@countRegistrados as varchar(3)) + ' Lote(s) ya registrado(s)'
select @error, @error_message
end
End

El original es este:


IF @object_type ='20' and @transaction_type in ('A','U')
BEGIN
if exists(Select distinct 'Error' from IBT1 B1 , IBT1 B2
where b1.BatchNum in (isnull(b2.BatchNum,'')) and B1.BaseEntry = @list_of_cols_val_tab_del
and b2.BaseEntry <> @list_of_cols_val_tab_del and b2.BaseType = 20 and b1.BaseType = 20 )
begin
SET @error = 2000
SET @error_message = 'Duplicte Batch not allowed'
end
End

Ya sea uno u otro, cualquiera de los dos validan perfecto, claro entre mas condiciones tenga será más rápida.


No se pudo conectar con la base de datos

 Hola, ¿Cómo están?, 

Les comparto un error que puede ser muy usual pero que no por eso tenemos siempre la solución a la mano, el error es el siguiente: No se pudo conectar con la base de datos 

Nos sucede al querer generar un PDF o un Informe Crystal Report, para arreglar esto no le demos tantas vueltas, solo requerimos instalar el SQL Client de SQL SERVER, con esto SAP ya contará con el acceso a la base de datos.



Espero les ayude a resolver de manera pronta este inconveniente.


domingo, 25 de abril de 2021

Inventarios - Stock por lote y ubicación

Hola, después de no publicar un buen rato, les traigo algo que les ayudará mucho, un informe de Stock por Lote y Ubicación, ya que por almacén ya se los tenia desde el 2016 desde este Enlace.

Pero estando trabajando ahora con ubicaciones, requerí tenerlo por ubicaciones y aquí se los comparto:

SELECT OBTN.[DistNumber], 
       OBBQ.[OnHandQty],
   OBBQ.[ItemCode], 
   OBIN.[BinCode],
   OBIN.[AbsEntry],
   OBBQ.[WhsCode]  FROM OBBQ /* Esta tabla  como pueden ver es la importante aquí  */ 
       INNER JOIN OBTN 
   ON OBTN.[AbsEntry] = OBBQ.[SnBMDAbs]
       INNER JOIN OBIN ON OBIN.[AbsEntry] = OBBQ.[BinAbs]
       WHERE OBBQ.[OnHandQty] > 0 
   order by OBBQ.[ItemCode]