Tech Tip
With UnForm 7.0,
Essence of
E-Delivery is Less Than 1K Bytes of Code
In the current evolution of UnForm 7.0, e-Delivery, what we call the process of
emailing and faxing documents defined by an UnForm rule-set out of a batch
print-stream, is a code-block-based construct that requires a single pre-page
and single post-page code-block.
For a base functionality set of
features, the amount of code required is under 800 bytes. To be fair, its under
800 bytes when you take off the leading white space to indent each code-block
line, a little more when you add the white space. Also to be fair, we shortened
the variable names to the bare minimum to get to that benchmark.
This Tech-Tip will discuss the
code so that an integrator can use this model as-is, as we have in updating our
demo samples starting at release level 7.0.11, or as a logical starting point
for a more full-featured e-Delivery implementation tailored to the needs of the
particular end user.
The idea for this article grew
out of our experience working on SDSI's new e-Deliver rule-set template and
engine project, which is now being distributed as free "beta" code, along with
the new e-Archive rule-set template which "templatizes" a pre-page code-block
and archive command to standardize the setting of archive properties for SDSI's
new document management components. There is a separate article in this
quarter's NewsPages covering these new features.
The total number of of
code-block script lines for the e-Deliver template and engine, because of the need for
a high level of flexibility in choosing both delivery methods and recipient
address and property retrieval methods, is "quite impressive", approaching
1,000 lines or so. Quite a bit more than 1K.
Having finished that project, we
wanted to boil it down to its essence, and that's what we'll be looking at here
in this article.
Base Functionality SPEC:
Email or fax via msfax documents
from a batch print-stream if an entity has an address or fax-phone on file in a
delimited text file and add a message to the print-copy which includes the
address or fax-phone delivered to.
Requirements:
UnForm 7.0; for MS-Fax requires
that the UnForm windows support server and and an MS Fax server be running and
accepting jobs, and for Email requires that a mail-server be running and
accessible with UnForm configured to point to it. These are standard
configuration elements for any UnForm installation.
Without further ado, here's the
code-block script:
THE 800-byte VERSION ....
prepage
{
if not(uf.subjob):
pi$ = get(71,4,7,"y",pagenum-1)
ti$ = get(71,4,7,"y")
ni$ = get(71,4,7,"y",pagenum+1)
if ti$<>pi$:
ek$=get(13,6,6,"y"),de=0,df=0,m$=""
a$=trim(getfilefield("addr_info",ek$,2,",",0))
if a$<>"":
dd=1,de=1,m$="Emailed:"
if not(pos("@"=ad$)):
df=1,de=0,m$="Faxed:"
endif
m$+=a$
endif
endif
if dd jobstore(tid$)
# if dd skip=1
endif
}
text 55,75,{m$},univers,12
postpage {
if not(uf.subjob):
if dd:
if nid$<>tid$:
f$=ti$+".pdf",dr$="pdf",ar$="-ce 1"
jobexec(ti$,f$,dr$,ar$)
fr$="support@sdsi.ws",su$="Doc "+tid$
if de email(a$,fr$,su$,"",f$)
if df:
t$=" subject="+chr(34)+su$+chr(34)
t$+=" name="+chr(34)+fr$+chr(34)
msfax(at$,a$,t$,e$)
endif
jobclose(ti$); dd=0
endif
endif
endif
}
|
RECOMMENDED VERSION:
( expanded, with longer, more
meaningful variable names, more white space )
# eDel <start>
#
prepage {
if not(uf.subjob):
prev_pg_docid$ = get(71,4,7,"y",pagenum-1)
this_pg_docid$ = get(71,4,7,"y")
next_pg_docid$ = get(71,4,7,"y",pagenum+1)
if this_pg_docid$<>prev_pg_docid$:
ent_key$=get(13,6,6,"y"),do_email=0,do_fax=0,msg$=""
addr$=trim(getfilefield("addr_info",ent_key$,2,",",0))
if addr$<>"":
do_deliver=1,do_email=1,msg$="Emailed
to:"
if not(pos("@"=addr$)):
do_fax=1,do_email=0,msg$="Faxed to:"
endif
msg$+=addr$
endif
endif
if do_deliver jobstore(this_pg_docid$)
# if do_deliver skip=1
endif
}
#
text 55,75,{msg$},univers,12
#
postpage {
if not(uf.subjob):
if do_deliver:
if next_pg_docid$<>this_pg_docid$:
attach$=this_pg_docid$+".pdf",driver$="pdf",args$="
-ce 1 "
jobexec(this_pg_docid$,attach$,driver$,args$)
from$="support@sdsi.ws",subj$="Doc
"+this_pg_docid$
if do_email
email(addr$,from$,subj$,"",attach$)
if do_fax:
tags$=" subject="+chr(34)+subj$+chr(34)
tags$+=" name="+chr(34)+from$+chr(34)
msfax(attach$,addr$,tags$,errmsg$)
endif
jobclose(this_pg_docid$);
do_deliver=0
endif
endif
endif
}
# eDel <eof>
|
Here are the basic things needed to
implement this:
- A functional enhancement
rule-set to add the e-Delivery code to.
- Column, row, length location
of a unique document ID, needed for multi-page documents.
- Column, row, length location
of an entity ID on the text document.
- Name of a comma-delimited text
file containing entries for entities with e-Delivery addresses.
- A from address for emailing, in this example it is
also used as the sender name for msfax.
Here's the main code-block elements in outline form:
prepage:
-
not(uf.subjob)
-
get() document id, with and without pagenum reference
-
this page doc id not equal to previous page doc id
-
get() entity key for address lookup
-
getfilefield() to get recipient address if any
-
do_deliver flag
-
jobstore() if do_deliver
precopy:
command area (outside of code-block):
postpage:
Here's a detailed discussion of each main code-block
elements:
prepage :
-
not(uf.subjob)
if
not(uf.subjob):
The e-delivery model uses UnForm's subjob functions to
build and launch a separate job for each document that needs to be
delivered. By default, a subjob will use the same rule-file and rule-set as
the main job, so the code which is added to determine whether e-delivery
will happen and to prepare for it only needs to be processed in the main job
itself, and NOT in the actual subjob which is building the individual
document for e-delivery purposes. The uf.subjob variable is an internal
global variable maintained by UnForm so that code can distinguish between
main jobs and subjobs. The colon at the end of the IF line is required when
using a BLOCK IF ... END IF multi-line IF construct.
-
get() document id, with and without pagenum
reference
prev_pg_docid$
= get(71,4,7,"y",pagenum-1)
this_pg_docid$ = get(71,4,7,"y")
next_pg_docid$ = get(71,4,7,"y",pagenum+1)
UnForm 7.0 added a new page parameter to the get() function, so the three
get() functions at the top of the prepage use the provided 71,4,7
col,row,cols location to get, in our case, a picking ticket number for the
previous, current and next page. Note that when on the first page, pagenum-1
equates to zero and refers to a non-existent page, so null will be returned,
and when on the last page, pagenum+1 equates to a non-existent page, and so
also will return null. The "y" parameter in the functions is a "trim" flag,
and instructs UnForm to trim leading and trailing spaces.
The doc id variables will be used to identify the subjob files and the email
and fax subject lines, and to control the timing of when key processes take
place.
-
this page doc id not equal to previous page doc id
if
this_pg_docid$<>prev_pg_docid$:
This starts a block of code that will only be processed
once, whenever it is the first page of a unique doc id. The process of
determining if there will be an e-delivery of a document only needs to
happen once, on the first (or only) page of a document, along with the
getting the recipient address.
-
get() entity key for address lookup
ent_key$=get(13,6,6,"y"),do_email=0,do_fax=0,msg$=""
Uses the get() function again on the current page to get an entity
id, in our example a customer number, from the col,row,cols locations given
for the text-page. Some control flags are also being initialized here.
-
getfilefield() to get recipient address if any
addr$=trim(getfilefield("addr_info",ent_key$,2,",",1))
The entity key retrieved in the previous step is used, along with the
"addr_info" text file name, to lookup the customer in the text file and
retrieve their delivery address. Field 2 in the text file contains the
delivery address in our sample, and the "," comma parameter supplies the
file delimiter. The ",1" as the last parameter is in the position for the
"trim" flag, indicating a trim of leading and trailing spaces.
If no key exists in the file for the given entity key, the addr$ variable
will be null, otherwise it will contain the delivery address.
-
do_deliver flag
if addr$<>"":
do_deliver=1,do_email=1,msg$="Emailed
to:"
if not(pos("@"=addr$)):
do_fax=1,do_email=0,msg$="Faxed to:"
endif
msg$+=addr$
endif
If the delivery address is not null, then it is OK to do
e-deliver, so the do_deliver flag is set to 1, and the defaults are set for
Email delivery. If there is no "@" symbol in the delivery address, then a
fax number is assumed, and the flag is set for fax, and email is turned off.
The address is then tacked onto the message variable, which was previously
set to the text version of the delivery type. Note that this whole block of
code is only executed if a non-null delivery address has been retrieved.
-
jobstore() if do_deliver
if do_deliver
jobstore(this_pg_docid$)
# if do_deliver skip=1
If the delivery flag is enabled then a jobstore() function is executed. This
is the first of the subjob functions we've seen, other than the check of the
uf.subjob global variable at the top. This function stores the current page
of text in a file associated with the named doc id. A subjob will not
actually be launched until we know we have all the pages, so the text for
this page and any subsequent pages for this doc id must be saved. Notice
that this line of code is outside of the IF...END IF block for the first
page of text, which means every page will hit this line, and if the
do_deliver flag was enabled (non-zero) from a previous page with the same
doc id, then the subsequent page gets stored as well using the jobstore().
The 2nd line prefixed with a "#" is an optional line which would skip laser
printing on this page if the document is going to be e-delivered.
Optionally, this skip logic could be inserted in a precopy code-block to
skip the printing of a particular copy of the document, if multiple copies
are configured.
THIS IS THE END OF PRE-PAGE
PROCESSING LOGIC FOR E-DELIVERY
command area (outside of
code-block) :
-
text command for delivery message
text
55,75,{msg$},univers,12
This command prints the value of the msg$ variable at the bottom right of a
laser-printed page. The msg$ variable contains the type and delivery address
from code in the prepage. This line would be optional and could be disabled
with a leading "#" character. If the skip page logic is employed from the
bottom of the e-deliver prepage, then the whole page would not be printed
and this line would be skipped anyway.
postpage :
-
not(uf.subjob)
Just the same as the if not(uf.subjob) at the top of the prepage, this whole
postpage set of logic is skipped if the subjob is being processed. It is
only needed while in the man job, to launch the e-delivery subjob and
processing for a doc id that requires e-delivery.
-
if do_deliver, and if next page docid$ not
equal to this page doc id
if do_deliver:
if next_pg_docid$<>this_pg_docid$:
The postpage contains the code to actually launch the subjob to
produce a pdf of the document, and invoke the email or fax commands to
deliver it. As such, it only needs to process the following code if the
deliver flag is enabled (non-zero).
Likewise, a check is made of the doc id for the next page to see if it is
time to proceed with e-delivery, or whether there is another page coming for
the same doc id. As such, it only needs to process the following code if the
doc id for the next page is different than the doc id for the current page.
-
jobexec()
attach$=this_pg_docid$+".pdf",driver$="pdf",args$="
-ce 1 "
jobexec(this_pg_docid$,attach$,driver$,args$)
This is the code which launches a subjob to create the ouput pdf file which
will be emailed or faxed. The jobexec() command, from its first parameter,
passes the name of the doc id which the jobstore() command used to store the
file. We are specifying that the output pdf file attach$ should be named
with the doc id and a .pdf extension. The driver is set as pdf, and the job
argument string, with the "-ce 1", instructs the subjob to only output copy
1, and not any of the other copies, if any, of the document. The jobexec()
command creates the output file which will be e-delivered.
-
email command
from$="support@sdsi.ws",subj$="Doc
"+this_pg_docid$
if do_email email(addr$,from$,subj$,"",attach$)
A couple of delivery property variables are set, the from and subject, and
if the do_email control flag is set, the email command is given, referencing
the delivery address, from and subject properties previously set, the body
property is skipped, and the name of the output file to attach is given with
attach$. Note that there are more properties available in the email command
after the attach file property, but we are not using any of them here.
-
msfax command
if do_fax:
tags$=" subject="+chr(34)+subj$+chr(34)
tags$+=" name="+chr(34)+from$+chr(34)
msfax(attach$,addr$,tags$,errmsg$)
Alternatively, if the do_fax control flag was set rather than the
do_email flag, then the subject and sender name properties are formatted
using the MS-Fax tag format. The chr(34) represents a double-quote mark,
which is necessary if a text string can contain spaces. Note the use of the
"+=" operator which concatenates strings together. The msfax command is then
given, which will submit the file attachment along with the delivery
fax-phone in addr$, and the tags, to the MS-Fax server, via the UnForm 7.0
Windows support server.
-
jobclose()
jobclose(this_pg_docid$);
The last of the subjob operations is the jobclose() command. This
closes and erases the job file which was used to accumulate the text pages
for the jobexec() command.
-
reset do_deliver flag
do_deliver=0
The last thing to do is reset the do_deliver control flag to zero,
so it will be initialized when the next page gets evaluated for whether
e-delivery is needed.
THIS IS THE END OF ALL
PROCESSING LOGIC
FOR E-DELIVERY
COOL, huh?
|