Enviar PDF de Pagos con job SQL Server SAP B1

Buen día Compañeros
El día de hoy les comparto como enviar un PDF del modulo de pagos recibidos mediante una jobs de SQL Server y varios procedimientos.
Para que esto funcione ya tendrías que haber realizado la configuración del database mail en sql server.
Y también haber instalado los runtime

32bit

h_tp://downloads.i-theses.com/?task=download_file&fileid=1014&no_html=1

64bit

h_tps://downloads.i-theses.com/component/downloads/?task=download_file&fileid=1015&no_html=1

También debemos tener los archivos: crexport.exe o CrystalReportsNinja.exe (no olvides cambiar el doc por el exe)
h_tps://drive.google.com/drive/folders/1IHX6bjKYYJkrqLQlbsIxhjiOYf7lLDHe

Primer paso:
Crear dos campos personalizados, dependiendo del uso, en mi caso realice dos, pero podría ser que solo se necesite uno. (Con validación de campos (SI, No)(Regular, Alfanumérico))
El primer campo define que no esta creado el PDF, que en el caso que sea no, el procedimiento que crea los PDF actuara.
El segundo campo defino que si se va a enviar el PDF, se usara el procedimiento para enviar por correo.
image

Segundo Paso:
Crear un Stored que nos va a generar el PDF

USE [MIBASE]
GO
/****** Object:  StoredProcedure [dbo].[PAGO_PDF]    Script Date: 25/11/2021 02:06:43 p. m. ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [dbo].[PAGO_PDF]

@DocKey int= NULL--,
--@ObjectId varchar(3) = NULL
--WITH ENCRYPTION

AS
BEGIN
	SET NOCOUNT ON;
	--*****GENERADOR DE PDF*****
	--Se declaran las variables de la tabla de usuario CS_ENVIOCORREOS
		Declare @dOCnUM varchar(10)
		Declare @Final varchar(1000)
		Declare @Resultado varchar(50)
		--Declare @DocKey int
		Declare @Parametro2 varchar(10)

		-----Convertir DocKey de int a varchar--------
		SET @Parametro2=CONVERT(varchar(10), @DocKey)
		-----Selecciona el DocNum buscando el Docentry---------------
		SET @dOCnUM = (Select DocNum from ORCT WHERE DocEntry=@DocKey )
		-----Muestra el resulto si se genera el PDF al final----------
		SET @Resultado='EXITO - Si se genero el PDF de la Pago '+CONVERT(varchar(10), @DocKey)
		Begin
						
						--Se juntan todos los parametros para juntar un solo parametro para CMD
						SET @Final = 'D:\SAP\crexport.exe -U MiUsuario -P MiContraseña -D MIBASE -S SERVIDOR  -F D:\SAP\Pagos\Pagos.rpt -O D:\SAP\Pagos\'+@dOCnUM+'.pdf -E pdf -a DocKey@:'+@Parametro2
						
						PRINT @Final
						--Ejecuta el generador de PDFs desde CMD----------------
						EXEC xp_cmdshell @Final

						----Actualiza el campo de PDF Generado de No a SI se genero--------
						update ORCT SET U_PDFGen='SI' WHERE ORCT.DocEntry=@DocKey							
						PRINT @Resultado
	

END
end

Tercer paso creamos otro stored que buscara los pagos que se deben convertir y enviar por correo:

USE [MiBase]
GO
/****** Object:  StoredProcedure [dbo].[CorreoPagos]    Script Date: 25/11/2021 02:34:31 p. m. ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO



CREATE PROCEDURE [dbo].[CorreoPagos]
AS
BEGIN
Declare @NoFact as int,@NoFactDoc as int
Declare @cliente as varchar(200)
Declare @Fecha date
Declare @Total as Decimal(20,2)
Declare @contador int
Declare @TotalUSD as varchar(10)
Declare @Correos as varchar(max)
Declare @ListaD as varchar(max)
Declare @CodigoCliente as varchar(40)

DECLARE @Ruta as varchar(500)
DECLARE @RutaPDF as varchar(500)
DECLARE @RFC as varchar(100)
DECLARE @XML as varchar(1000)
DECLARE @PDF as varchar (500)
DECLARE @Cadena as varchar (500)
DECLARE @RUTA2 AS varchar(200)
DECLARE @NoFol as varchar(40)
DeCLARE @DocNum int

SET @contador =(SELECT COUNT(T0.[DocEntry])  
                FROM [dbo].ORCT  T0 INNER JOIN  ECM2 T1 ON T0.[DocEntry] =T1.[SrcObjAbs] 
				WHERE T1.[SrcObjType]  =24  and T0.U_PDFEnvio='SI' /*and T0.DocNum=@DocEntry*/)
--(SELECT count(T0.[DocEntry]) FROM ORCT T0 WHERE
	--T0.U_PDFEnvio='SI' and T0.DocNum=@NoFact) --Busca cuantos PDF se generaron en la tabla de factura deudores principal
if ISNULL(@contador,0) >0 

begin

SET @NoFact =(SELECT MAX(T0.[DocEntry]) FROM ORCT T0 WHERE
	T0.U_PDFEnvio='SI' /*and T0.DocNum=@DocEntry*/ ) --14353) Busca la llave primaria 
-------SET @NoFact =(SELECT MAX(T0.[DocEntry]) FROM ORCT T0 WHERE
	--------T0.U_PDFEnvio='SI') --14353) Busca la llave primaria mas reciente que indique que si se debe generar el PDF
	--LISTA DE CORREOS
	----SET @ListaD =(SELECT T0.[U_Correo]
	----			FROM ORCT T0 WHERE T0.[DocEntry]=@NoFact)--14353)--@NoFact)	--Busca los correos con la llave primaria encontrada en la parte de arriba


	exec [PAGO_PDF] @NoFact

		

	SET @NoFactDoc =(SELECT T0.DocNum FROM ORCT T0 WHERE
	T0.[DocEntry] = @NoFact)	
 SET @CodigoCliente = (SELECT T0.[CardCode] FROM ORCT T0 WHERE T0.[DocEntry]=@NoFact) 
 SET @cliente = (SELECT T0.[CardName] FROM ORCT T0 WHERE T0.[DocEntry]=@NoFact)   
 SET @Fecha = (SELECT T0.[DocDate] FROM ORCT T0 WHERE T0.[DocEntry]=@NoFact)
--Condicion del Total, si DocTotalFC es igual a 0 slecciona a DocTotal
  SET @Total=(SELECT CASE T1.DocTotalFC WHEN 0 THEN T1.DocTotal ELSE T1.DocTotalFC END AS 'TOTAL' FROM [dbo].ORCT T1 WHERE T1.[DocEntry]=@NoFact)
  SET @NoFol = (SELECT T0.ReportID FROM ECM2 T0 WHERE  T0.[SrcObjType]=24 AND T0.[SrcObjAbs]=@NoFact)
  
  SET @ListaD =(SELECT T0.[U_ListaDistrib] FROM CRD1 T0 WHERE T0.[CardCode] =@CodigoCliente and T0.[Address] ='PAGOS')


  SET @Correos = @ListaD
DECLARE @Body NVARCHAR(MAX),
    @TableHead VARCHAR(max),
    @TableTail VARCHAR(max)

set @RUTA2= (select convert(varchar(4),year(t0.DocDate))+'-' + RIGHT('00' + Ltrim(Rtrim(month(t0.DocDate))),2) +'\'+T0.CardCode+'\RC\'
from ORCT t0 WHERE t0.DocEntry=@NoFact)
SET @Ruta = (select convert(varchar(249),XmlPath)+'0010000100\0010000100\'+@RUTA2 from OADM)
SET @Rutapdf = ('D:\SAP\Pagos\' )
	SET @RFC =  (SELECT TaxIdNum FROM OADM)
    SET @XML  = (@Ruta +   @NoFol + '.xml')
    SET @PDF = ('D:\SAP\Pagos\'+convert(varchar(30),@NoFactDoc)+'.pdf')    
    SET @Cadena = (@XML + ';' + @PDF)

DECLARE @HTML varchar(8000)
	SET @HTML=
	/*N'Pago Fiscal Electrónico, enviada desde el Servidor......'+'..No de Documento Electrónico: '
	+@NoFol+'..Folio Interno:..'+convert(varchar(20),   @NoFactDoc)+ 
	'..Nombre del Cliente:.. '  + @cliente +''

declare @table nvarchar(max)

set @table =*/
N'<html>'+
N'<head>'+
N'<style type="text/css">table{border: solid 1px;border-collapse:collapse;}td{text-align:"center";}.izq{text-align:left}th{text-align:"center";  background:"#808080"; color:"#ffffff";}</style>'+
N'</head>'+
N'<body>'+
N'<h3><center><u>PAGO FISCAL ENVIANDO DESDE EL SERVIDOR<u></center></h3>'+
N'<table border="1" align = "center" style="width: 100%">' +
N'<tr>'+
N'<th>Documento Electronico</th>'+
N'<th>Folio Interno </th>'+
N'<th>Cliente</th>'+
N'</tr>'+
N'<tr style="text-align:center;">'+
N'<td>'+' '+@NoFol+' '+'</td>'+
N'<td>'+' '+convert(varchar(20),@NoFactDoc)+' '+'</td>'+
N'<td>'+' '+@cliente+' '+'</td>'+
N'</tr>'+
N'</table>'+
N'<body>'+
N'<html>';
	if ISNULL(@contador,0) >0 
	begin

		Declare @asunto varchar(120)
		SEt @asunto= ('SIP ENVIO DE PAGOS: '+ convert(varchar(10),@NoFactDoc))

	
		EXEC msdb.dbo.sp_send_dbmail
		@profile_name = 'Notificaciones', -- replace with your SQL Database Mail Profile 
		--@body = @Body,
		@body = @HTML,
		@body_format ='HTML',
		@recipients =@ListaD,--'correo@hotmail.com',
		@copy_recipients =' correo2@outlook.com',
		--@ListaD,--'Correo3@gmail.com',--@ListaD, --'Correo4@gmail.com',--@Mandar, -- replace with your email address
		@subject = @asunto ,
		@file_attachments=@Cadena;
     
update ORCT SET U_PDFEnvio='ENV' WHERE ORCT.DocEntry=@NoFact
end;
end;

END

Cuarto Paso: Crearemos otro Stored el cual crea el ciclo para convertir y enviar todos los PDF que están pendientes en sistema.

USE [MiBase]
GO
/****** Object:  StoredProcedure [dbo].[RepitProcessPagos]    Script Date: 25/11/2021 02:57:55 p. m. ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATEPROCEDURE [dbo].[RepitProcessPagos] 
	-- Add the parameters for the stored procedure here
	
AS
BEGIN
Declare @seleccion as nvarchar(20)
Declare @contador as int

Set @seleccion=(SELECT MAX(T0.U_PDFEnvio) FROM ORCT T0 WHERE T0.U_PDFEnvio='SI')
Set @contador=(SELECT COUNT(T0.U_PDFEnvio) FROM ORCT T0 WHERE T0.U_PDFEnvio='SI')

While(@contador > 0)
	Begin
	exec CorreoPagos
	set @contador = @contador -1
	End

End

Creamos el Job

Vamos a Steps y Damos clic en nuevo

Asignamos un nombre y seleccionamos la base de datos y agregamos el nombre del procedimiento del ciclo.

Ahora vamos a Schedules
Configuramos la tarea en mi caso la configure para diario a la 13 hrs

Después de eso solo ok y nuestra tarea ya esta creada solo restar iniciarla.
Si tienes alguna duda no olvides contactarme.

7 Me gusta

Gracias por tu aportación.
Lo voy a probar pero con las facturas.

Ya te contaré que tal me ha ido.

:slight_smile:

1 me gusta

Ya había publicado el de las facturas!
(ht_ps://consultoria-sap.github.io/business-one/sql/enviar-facturas-sql.html)
Pero lo volveré a publicar más adelante ya que hice cambios!

1 me gusta

Interesante…
Lo probaré para testear y ver si aplica su utilidad.
Gracias.

2 Me gusta

Buenas noches. Excelente aporte, mucha gracias!!!
Una duda: veo que actualizas directamente la tabla ORCT de SAP B1. Tenía entendido que SAP no te permite guardar información directamente en sus tablas, ¿no es así?.

Gracias.
saludos…

Es un campo definido por el usuario, con eso no hay tanto problema!

Hola Buen dia @kriptonniano me puse a implementar tu codigo, pero con pagos efectuados y no pagos recibidos, solo que me surguieron 2 dudas

la 1.- ya cambien la tabla OCRT que tu tienes para pagos recibidos y ligue la tabla OVPM de pagos efectuados ya logre crear un pdf porque le pude a dos pagos la condicion de pdf generado como NO en el campo definido y en donde dice Pdf Enviado le puse la condicion SI el unico incoveniente que me tope es que nomas me esta creando un pdf en mi caso el primero y no me crea el anterior supongamos creo el 14017 y me debio de haber creado 14017 y 14016( PD. son números de documento en sap creados)

2.- la Otra fue que al momento de querer enviar correos no necesito que me mande el XML Pero si el PDF pero me encontre con el incoveniente de que no me adjunto el PDF osea si envia el documento pero no envia el documento.

3.- una tercera consulta aprovechando vi que tienes un campo definido creado en sap en la siguiente consulta : SET @ListaD =(SELECT T0.[U_ListaDistrib] FROM CRD1 T0 WHERE T0.[CardCode] =@CodigoCliente and T0.[Address] =‘PAGOS’)

queria saber si en ese codigo pones la lista de distribuccion de los correos que hay que enviar por ejemplo tengo un cliente que normalmente me pide 3 correos ahi en ese caso como le podria hacer con tu codigo…

4.- Perdon bro una cuarta, como puedo modificar el cuerpo del correo por ejemplo escribir que diga
Estimado proveedor: en el correo encontrara correo adjunto con informacion relevante de su pago … o ( Lo que sea solo quiero escribir algo en el cuerpo del correo )

quedo al pendiente

Hola buen Dia @kriptonniano

al parecer en mi consulta la pregunta una y dos ya estan resueltas este caso no sabia como los procesaba pero la solucion fue ejecutar de nuevo el stored para que lo vuelva a repetir y lo este ejecutando sin problemas cada ves que genero el pago…

la numero dos tenia un problema con el atachment tenia xml y pdf pero en mi caso como este no necesito el xml elimine que no lo adjuntara porque ahi era donde tenia el problema

solo me surgieron estas dos dudas que si estan pendientes

3.- una tercera consulta aprovechando vi que tienes un campo definido creado en sap en la siguiente consulta : SET @ListaD =(SELECT T0.[U_ListaDistrib] FROM CRD1 T0 WHERE T0.[CardCode] =@CodigoCliente and T0.[Address] =‘PAGOS’)

queria saber si en ese codigo pones la lista de distribuccion de los correos que hay que enviar por ejemplo tengo un cliente que normalmente me pide 3 correos ahi en ese caso como le podria hacer con tu codigo…

4.- Perdon bro una cuarta, como puedo modificar el cuerpo del correo por ejemplo escribir que diga
Estimado proveedor: en el correo encontrara correo adjunto con informacion relevante de su pago … o ( Lo que sea solo quiero escribir algo en el cuerpo del correo )

Estimado,
Lo configure pero al correo el SP de CrearPDF , me aparece el siguiente error :
" System Error: No se abrió el documento."

Hola para tu primer duda, revisa si tienes todo correcto en el procedimiento que repite el proceso el cual lleva de nombre:
"[dbo].[RepitProcessPagos] "

La segunda podrías revisar las rutas, tal vez por eso no lo envía porque no lo esta encontrando en la ruta que estas colocando.

Tercera: efectivamente ese campo es donde se colocan los correos separados por punto y coma “;”

Cuarta:

N'<html>'+
N'<head>'+
N'<style type="text/css">table{border: solid 1px;border-collapse:collapse;}td{text-align:"center";}.izq{text-align:left}th{text-align:"center";  background:"#808080"; color:"#ffffff";}</style>'+
N'</head>'+
N'<body>'+
N'<h3><center><u>Aquí pon tu texto<u></center></h3>'+
N'<table border="1" align = "center" style="width: 100%">' +
N'<tr>'+
N'<th>Documento Electronico</th>'+
N'<th>Folio Interno </th>'+
N'<th>Cliente</th>'+
N'</tr>'+
N'<tr style="text-align:center;">'+
N'<td>'+' '+@NoFol+' '+'</td>'+
N'<td>'+' '+convert(varchar(20),@NoFactDoc)+' '+'</td>'+
N'<td>'+' '+@cliente+' '+'</td>'+
N'</tr>'+
N'</table>'+
N'<body>'+
N'<html>';

Puedes ser mas especifico.

Hola que tal. He replicado pero cuando lo ejecuto dice que no encuentra el reporte.rpt para generar el PDF.

Respondiendo a mi propio comentario y por si a alguien le sirve. He realizado lo siguiente.

1.He creado una vista
2. He creado una plantilla con crystal reports
3. He realizado la conexion a la vista en el reporte creado.
4. He creado un filtro en el cual solicito el DocEntry o DocNum del documento y con eso me ha generado el PDF.

1 me gusta