Files
MBS/PROYECTO/otrodir/email_factura.4gl
T

412 lines
12 KiB
Plaintext

-- email_factura.4gl
IMPORT os
IMPORT JAVA java.lang.System
IMPORT JAVA java.io.ByteArrayOutputStream
IMPORT JAVA java.io.PrintStream
IMPORT JAVA java.util.Properties
IMPORT JAVA javax.mail.Session
IMPORT JAVA javax.mail.Message
IMPORT JAVA javax.mail.Transport
IMPORT JAVA javax.mail.internet.InternetAddress
IMPORT JAVA javax.mail.internet.MimeMessage
IMPORT JAVA javax.mail.internet.MimeMultipart
IMPORT JAVA javax.mail.internet.MimeBodyPart
IMPORT JAVA com.sun.mail.smtp.SMTPTransport
IMPORT security
CONSTANT debug_level = 1
DEFINE logtext STRING
DEFINE out_stream ByteArrayOutputStream
DEFINE xpassword STRING
TYPE cnf_t RECORD
hostname STRING,
smtphost STRING,
smtpport INTEGER,
senderemail STRING,
smtpauth SMALLINT,
username STRING,
password STRING,
use_ssl SMALLINT,
use_tls SMALLINT,
cnxtimeout INTEGER
END RECORD
DEFINE cnf cnf_t
FUNCTION enviaFilesCliente(rncempresa,ptipo_cliente,psec_cliente,rnc,ncf,porden,pconduce,pbodega)
DEFINE email, cuerpo_correo, xusername, xsmtphost, xsmtpport, xpassword STRING
DEFINE subject, attachment, nombre_cliente STRING
DEFINE filefirmado, ruta_firmados,ncf STRING,
ptipo_cliente,psec_cliente,i,porden,pconduce,pbodega INT,
rnc,rncempresa VARCHAR(11),
verdad BOOLEAN,
rutas DYNAMIC ARRAY OF STRING
DEFINE attachments DYNAMIC ARRAY OF STRING
DEFINE ruta_doc, nombre_doc,selec,temp_dir STRING
DEFINE bin_doc BYTE
DEFINE temp_file STRING
LET email = NULL
LET nombre_cliente = NULL
SELECT a.patente,a.nombre
INTO email,nombre_cliente
FROM vetb00004 a
WHERE a.tipo_cliente = ptipo_cliente
AND a.sec_cliente = psec_cliente
IF email IS NULL OR email = "" THEN
LET email = "apereyra@marmotech.com.do"
ELSE
LET email = email CLIPPED,",apereyra@marmotech.com.do"
END IF
IF nombre_cliente IS NULL OR nombre_cliente = "" THEN
LET nombre_cliente = "Cliente"
END IF
DISPLAY BY NAME email
LET temp_dir = "E:\\MARMOTECH\\temp\\"
LET i = 1
-- 1. XML siempre primero
LET rutas[1] = "E:\\MARMOTECH\\BIN320\\filesxml\\firmados\\"
LET rutas[2] = "E:\\MARMOTECHC\\BIN320\\filesxml\\firmados\\"
FOR i = 1 TO rutas.getLength()
LET filefirmado = rutas[i] CLIPPED,
rncempresa CLIPPED,
ncf CLIPPED,
".xml"
IF os.Path.exists(filefirmado) THEN
LET attachments[i] = filefirmado
EXIT FOR
END IF
END FOR
LET selec = "SELECT a.nombre_file, a.documento
FROM marmotech.dbo.prtb00029 a
WHERE a.num_oc =?
AND a.num_doc = ?
AND a.bodega = ?
AND a.tipo_file = 'CO'
"
PREPARE comando FROM selec
DECLARE c_docs CURSOR FOR comando
OPEN c_docs USING porden,pconduce,pbodega
LET i = attachments.getLength() + 1
LOCATE bin_Doc IN MEMORY
FETCH c_docs INTO nombre_doc, bin_doc
WHILE STATUS = 0
IF nombre_doc IS NULL OR nombre_doc = "" THEN
LET nombre_doc = SFMT("doc_%1.pdf", i)
END IF
LET temp_file = SFMT("%1%2", temp_dir, nombre_doc)
CALL save_binary_to_file(temp_file, bin_doc)
IF os.Path.exists(temp_file) THEN
LET attachments[i] = temp_file
LET i = i + 1
END IF
FETCH c_docs INTO nombre_doc, bin_doc
END WHILE
CLOSE c_docs
DISPLAY "Attachments:"
FOR i = 1 TO attachments.getLength()
DISPLAY attachments[i]
END FOR
LET subject = SFMT("XML Facturacion Electronica - NCF %1", ncf)
LET xusername = "notificacion@marmotech.com.do"
LET xsmtphost = "smtp.office365.com"
LET xsmtpport = "587"
LET xpassword = "Lmmjvsd2020"
LET cuerpo_correo = build_html_factura(nombre_cliente, ncf, rnc)
CALL enviaemail2(
email,
subject,
cuerpo_correo,
attachments,
xusername,
xsmtphost,
xsmtpport,
xpassword
)
RETURNING verdad
RETURN verdad
END FUNCTION
FUNCTION build_html_factura(nombre_cliente, ncf, rnc)
DEFINE nombre_cliente, ncf, rnc STRING
DEFINE html STRING
LET html =
"<!DOCTYPE html>" ||
"<html>" ||
"<head>" ||
"<meta charset='UTF-8'>" ||
"<style>" ||
"body{margin:0;padding:0;background:#f5f6fa;font-family:Arial,sans-serif;color:#2d3436;}" ||
".wrapper{padding:24px;}" ||
".card{max-width:680px;margin:0 auto;background:#ffffff;border:1px solid #dfe6e9;border-radius:8px;overflow:hidden;}" ||
".header{background:#0b5ed7;color:#ffffff;padding:20px 24px;font-size:22px;font-weight:bold;}" ||
".content{padding:24px;font-size:14px;line-height:1.6;}" ||
".label{font-weight:bold;color:#2c3e50;}" ||
".box{background:#f8f9fa;border:1px solid #e9ecef;border-radius:6px;padding:14px;margin-top:16px;}" ||
".footer{padding:16px 24px;background:#f1f3f5;color:#636e72;font-size:12px;}" ||
"</style>" ||
"</head>" ||
"<body>" ||
"<div class='wrapper'>" ||
"<div class='card'>" ||
"<div class='header'>Factura Electronica</div>" ||
"<div class='content'>" ||
"Estimado(a) <span class='label'>" || nombre_cliente CLIPPED || "</span>,<br><br>" ||
"Adjunto encontrara el archivo XML firmado correspondiente a su comprobante electronico emitido por MARMOTECH, S. A..<br>" ||
"<div class='box'>" ||
"<span class='label'>NCF:</span> " || ncf CLIPPED || "<br>" ||
"<span class='label'>RNC Emisor:</span> " || rnc CLIPPED || "<br>" ||
"<span class='label'>Documento adjunto:</span> XML firmado" ||
"</div>" ||
"<br>Este mensaje fue generado automaticamente por el sistema MBS." ||
"</div>" ||
"<div class='footer'>" ||
"Por favor, no responda este correo. Si necesita asistencia, comuníquese con nuestro departamento de soporte." ||
"</div>" ||
"</div>" ||
"</div>" ||
"</body>" ||
"</html>"
RETURN html
END FUNCTION
-- enviaemail.4gl
FUNCTION enviaemail2(rcpt_to, subject, body, attachments, xusername, xsmtphost, xsmtpport, xpassword)
DEFINE rcpt_to, subject, body, xusername, xsmtphost, xsmtpport, xpassword STRING
DEFINE attachments DYNAMIC ARRAY OF STRING
DEFINE msg MimeMessage
DEFINE body_part MimeBodyPart
DEFINE attach_part MimeBodyPart
DEFINE multipart MimeMultipart
DEFINE sesion Session
DEFINE plain_password, s_proto STRING
DEFINE trans Transport
DEFINE i INT
LET cnf.smtphost = xsmtphost
LET cnf.smtpport = xsmtpport
LET cnf.username = xusername
LET cnf.password = xpassword
LET cnf.senderemail = xusername
LET cnf.smtpauth = TRUE
LET cnf.use_ssl = FALSE
LET cnf.use_tls = TRUE
LET cnf.cnxtimeout = 30
CALL create_cxion_session() RETURNING sesion, plain_password, s_proto
LET msg = MimeMessage.create(sesion)
CALL msg.setFrom(InternetAddress.create(xusername))
CALL msg.setSubject(subject,"UTF-8")
CALL msg.addHeader("To", rcpt_to)
CALL msg.addHeader("MIME-Version", "1.0")
LET body_part = MimeBodyPart.create()
CALL body_part.setContent(body, "text/html; charset=UTF-8")
LET attach_part = MimeBodyPart.create()
LET multipart = MimeMultipart.create()
CALL multipart.addBodyPart(body_part) -- ? FALTABA
FOR i = 1 TO attachments.getLength()
IF attachments[i] IS NOT NULL AND os.Path.exists(attachments[i]) THEN
LET attach_part = MimeBodyPart.create()
CALL attach_part.attachFile(attachments[i])
CALL multipart.addBodyPart(attach_part)
END IF
END FOR
CALL msg.setContent(multipart)
CALL msg.saveChanges()
LET trans = sesion.getTransport(s_proto)
CALL trans.connect(xsmtphost, xusername, plain_password)
CALL trans.sendMessage(
msg,
InternetAddress.parse(rcpt_to)
)
CALL trans.close()
RETURN TRUE
END FUNCTION
PRIVATE FUNCTION create_cxion_session()
DEFINE s_proto, s_password STRING
DEFINE x_timeout INTEGER
DEFINE sess Session
DEFINE props Properties
DEFINE custom_ps PrintStream
CALL show_debug_msg(1, "Preparing connection parameters ...")
CALL string_to_base64(cnf.password) RETURNING cnf.password
LET s_password = base64_to_string(cnf.password)
IF cnf.cnxtimeout > 0 THEN
LET x_timeout = cnf.cnxtimeout * 1000
ELSE
LET x_timeout = 0
END IF
LET cnf.use_tls = TRUE
LET cnf.use_ssl = FALSE
IF cnf.use_ssl THEN
LET s_proto = "smtps"
ELSE
LET s_proto = "smtp"
END IF
LET props = System.getProperties()
IF cnf.use_ssl THEN
CALL setMailProperties(props, "smtp", "ssl.enable", "true")
ELSE
CALL setMailProperties(props, "smtp", "ssl.enable", "false")
END IF
IF cnf.smtpauth THEN
CALL setMailProperties(props, s_proto, "auth", "true")
ELSE
CALL setMailProperties(props, s_proto, "auth", "false")
END IF
CALL setMailProperties(props, s_proto, "host", cnf.smtphost)
CALL setMailProperties(props, s_proto, "port", cnf.smtpport)
CALL setMailProperties(props, s_proto, "connectiontimeout", x_timeout)
CALL setMailProperties(props, s_proto, "timeout", x_timeout)
CALL setMailProperties(props, s_proto, "writetimeout", x_timeout)
IF cnf.use_tls THEN
CALL setMailProperties(props, s_proto, "starttls.enable", "true")
CALL setMailProperties(props, s_proto, "ssl.checkserveridentity", "false")
CALL setMailProperties(props, s_proto, "ssl.trust", "*")
ELSE
CALL setMailProperties(props, s_proto, "starttls.enable", "false")
END IF
LET sess = Session.getInstance(props)
LET out_stream = ByteArrayOutputStream.create()
LET custom_ps = PrintStream.create(out_stream)
CALL sess.setDebugOut(custom_ps)
CALL sess.setDebug(TRUE)
RETURN sess, s_password, s_proto
END FUNCTION
FUNCTION base64_to_string(str_b64)
DEFINE str_out, str_b64, str_aux STRING
TRY
CALL security.Base64.ToString(str_b64) RETURNING str_out
CATCH
LET str_aux = "Unable to convert the Base64 string into plain-text: ", STATUS
CALL mbox_ok("Error", str_aux, "stop")
LET str_out = NULL
END TRY
RETURN str_out
END FUNCTION
FUNCTION string_to_base64(str_ent)
DEFINE str_ent, str_b64, str_aux STRING
TRY
CALL security.Base64.FromString(str_ent) RETURNING str_b64
CATCH
LET str_aux = "Unable to convert the input string into Base64: ", STATUS
CALL mbox_ok("Error", str_aux, "stop")
LET str_b64 = NULL
END TRY
RETURN str_b64
END FUNCTION
PRIVATE FUNCTION setMailProperties(props, prot, prop, val)
DEFINE props Properties
DEFINE auxi, prot, prop, val STRING
LET auxi = SFMT("mail.%1.%2", prot, prop)
CALL props.put(auxi, val)
CALL show_debug_msg(1, SFMT("Property '%1' set to value '%2'", auxi, val))
END FUNCTION
PRIVATE FUNCTION show_debug_msg(lev, msg)
DEFINE lev SMALLINT
DEFINE msg STRING
IF lev >= debug_level THEN
DISPLAY msg
END IF
END FUNCTION
FUNCTION mbox_ok(t, m, i)
DEFINE t, m, i STRING
MENU t ATTRIBUTES(STYLE="dialog", COMMENT=m, IMAGE=i)
COMMAND "Ok"
EXIT MENU
END MENU
END FUNCTION
FUNCTION save_binary_to_file(path, data)
DEFINE path STRING
DEFINE data BYTE
DEFINE ch base.Channel
DEFINE size INTEGER
DISPLAY "path: ", path
LET ch = base.Channel.create()
CALL ch.openFile(path, "wb")
LET size = LENGTH(data)
IF size > 0 THEN
#CALL ch.write(data)
CALL data.writeFile(path)
ELSE
DISPLAY "ERROR: binary vacío"
END IF
CALL ch.close()
END FUNCTION