S_208FMF

LANSA

S_208FMF
* ===================================================================
*
* Component : S_208FMF
* Type : Form
* Ancestor : PRIM_FORM
*
* Description : Main Email Message Processor
*
* Disclaimer : The following material is supplied as example material
* only. No warranty concerning this material or its use
* in any way whatsoever is expressed or implied.
*
* ===================================================================
FUNCTION OPTIONS(*DIRECT)
BEGIN_COM FORMPOSITION(ScreenCenter) HEIGHT(415) LAYOUTMANAGER(#SPLM_1) LEFT(422) TOP(24) VISUALSTYLE(#VS_NORM) WIDTH(520)

* Main form layout details

DEFINE_COM CLASS(#PRIM_SPLM) NAME(#SPLM_1)
DEFINE_COM CLASS(#PRIM_PANL) NAME(#TOP_PANEL) DISPLAYPOSITION(3) HEIGHT(156) LEFT(0) PARENT(#COM_OWNER) TABPOSITION(3) TABSTOP(False) TOP(0) WIDTH(512)
DEFINE_COM CLASS(#PRIM_PANL) NAME(#BOTTOM_PANEL) DISPLAYPOSITION(4) HEIGHT(228) LAYOUTMANAGER(#SPLM_2) LEFT(0) PARENT(#COM_OWNER) TABPOSITION(4) TABSTOP(False) TOP(160) WIDTH(512)
DEFINE_COM CLASS(#PRIM_SPLI) NAME(#SPLI_1) MANAGE(#TOP_PANEL) PARENT(#SPLM_1) WEIGHT(1)
DEFINE_COM CLASS(#PRIM_SPLI) NAME(#SPLI_2) MANAGE(#BOTTOM_PANEL) PARENT(#SPLM_1)
DEFINE_COM CLASS(#PRIM_SPLM) NAME(#SPLM_2) DIVIDERSTYLE(Gap) ORIENTATION(Vertical)
DEFINE_COM CLASS(#PRIM_PANL) NAME(#LEFT_BOTTOM_PANEL) DISPLAYPOSITION(1) HEIGHT(228) LAYOUTMANAGER(#ATLM_2) LEFT(0) PARENT(#BOTTOM_PANEL) TABPOSITION(1) TABSTOP(False) TOP(0) WIDTH(226)
DEFINE_COM CLASS(#PRIM_PANL) NAME(#RIGHT_BOTTOM_PANEL) DISPLAYPOSITION(2) HEIGHT(228) LAYOUTMANAGER(#ATLM_1) LEFT(230) PARENT(#BOTTOM_PANEL) TABPOSITION(2) TABSTOP(False) TOP(0) WIDTH(282)
DEFINE_COM CLASS(#PRIM_SPLI) NAME(#SPLI_3) MANAGE(#LEFT_BOTTOM_PANEL) PARENT(#SPLM_2)
DEFINE_COM CLASS(#PRIM_SPLI) NAME(#SPLI_4) MANAGE(#RIGHT_BOTTOM_PANEL) PARENT(#SPLM_2) WEIGHT(1)
DEFINE_COM CLASS(#PRIM_LABL) NAME(#LABL_1) CAPTION('To start this example please follow these instructions:') DISPLAYPOSITION(1) HEIGHT(20) LEFT(4) PARENT(#TOP_PANEL) TABPOSITION(1) TABSTOP(False) TOP(4) WIDTH(261)
DEFINE_COM CLASS(#PRIM_LABL) NAME(#LABL_2) CAPTION('(1) Start you email system (eg: MS-Outlook) running') DISPLAYPOSITION(2) HEIGHT(20) LEFT(30) PARENT(#TOP_PANEL) TABPOSITION(2) TABSTOP(False) TOP(23) WIDTH(250)
DEFINE_COM CLASS(#PRIM_LABL) NAME(#LABL_3) CAPTION('(2) Connect to to your iSeries Server system ----------------->') DISPLAYPOSITION(3) HEIGHT(20) LEFT(30) PARENT(#TOP_PANEL) TABPOSITION(3) TABSTOP(False) TOP(45) WIDTH(267)
DEFINE_COM CLASS(#PRIM_LABL) NAME(#LABL_4) CAPTION('(3) Connect to your email system ---------------------------------->') DISPLAYPOSITION(4) HEIGHT(20) LEFT(30) PARENT(#TOP_PANEL) TABPOSITION(4) TABSTOP(False) TOP(67) WIDTH(267)
DEFINE_COM CLASS(#PRIM_LABL) NAME(#LABL_5) CAPTION('(4) Start processing inbound emails ------------------------------> ') DISPLAYPOSITION(5) HEIGHT(20) LEFT(30) PARENT(#TOP_PANEL) TABPOSITION(5) TABSTOP(False) TOP(88) WIDTH(267)
DEFINE_COM CLASS(#PRIM_LABL) NAME(#LABL_6) CAPTION('(5) Leave this application running (minimized if desired) ') DISPLAYPOSITION(6) HEIGHT(20) LEFT(30) PARENT(#TOP_PANEL) TABPOSITION(6) TABSTOP(False) TOP(111) WIDTH(267)
DEFINE_COM CLASS(#PRIM_LABL) NAME(#LABL_7) CAPTION('(6) Send emails containing attachments to your inbox ') DISPLAYPOSITION(7) HEIGHT(20) LEFT(30) PARENT(#TOP_PANEL) TABPOSITION(7) TABSTOP(False) TOP(133) WIDTH(258)
DEFINE_COM CLASS(#PRIM_ATLM) NAME(#ATLM_1) MARGINTOP(4)
DEFINE_COM CLASS(#PRIM_ATLM) NAME(#ATLM_2) MARGINTOP(4)
DEFINE_COM CLASS(#PRIM_LTVW) NAME(#EVENT_LOG) DISPLAYPOSITION(1) FULLROWSELECT(True) HEIGHT(195) LEFT(8) PARENT(#EVENT_LOG_GROUP) SELECTIONSTYLE(Single) TABPOSITION(1) TOP(21) WIDTH(210)
DEFINE_COM CLASS(#PRIM_GPBX) NAME(#EVENT_LOG_GROUP) CAPTION('Event Log') DISPLAYPOSITION(1) HEIGHT(224) LAYOUTMANAGER(#ATLM_3) LEFT(0) PARENT(#LEFT_BOTTOM_PANEL) TABPOSITION(1) TABSTOP(False) TOP(4) WIDTH(226)
DEFINE_COM CLASS(#PRIM_SPLI) NAME(#SPLI_5) MANAGE(#EVENT_LOG_GROUP) PARENT(#SPLM_1)
DEFINE_COM CLASS(#PRIM_ATLI) NAME(#ATLI_3) ATTACHMENT(Center) MANAGE(#EVENT_LOG_GROUP) PARENT(#ATLM_2)
DEFINE_COM CLASS(#PRIM_ATLM) NAME(#ATLM_3) MARGINBOTTOM(4) MARGINLEFT(4) MARGINRIGHT(4) MARGINTOP(8)
DEFINE_COM CLASS(#PRIM_ATLI) NAME(#ATLI_4) ATTACHMENT(Center) MANAGE(#EVENT_LOG) PARENT(#ATLM_3)
DEFINE_COM CLASS(#PRIM_ATLI) NAME(#ATLI_1) ATTACHMENT(Center) MANAGE(#EVENT_LOG) PARENT(#ATLM_2)
DEFINE_COM CLASS(#PRIM_LVCL) NAME(#LVCL_1) CAPTION('Event ') CAPTIONTYPE(Caption) DISPLAYPOSITION(2) PARENT(#EVENT_LOG) SOURCE(#SYSVAR$AV) WIDTH(20) WIDTHTYPE(Remainder)
DEFINE_COM CLASS(#PRIM_LVCL) NAME(#LVCL_2) CAPTION('Time') CAPTIONTYPE(Caption) DISPLAYPOSITION(1) PARENT(#EVENT_LOG) SOURCE(#TIME) WIDTH(25) WIDTHTYPE(Fixed)
DEFINE_COM CLASS(#PRIM_LTVW) NAME(#MAIL_LIST) DISPLAYPOSITION(1) FULLROWSELECT(True) HEIGHT(195) LEFT(8) PARENT(#MAIL_LIST_GROUP) SELECTIONSTYLE(Single) TABPOSITION(1) TOP(21) WIDTH(266)
DEFINE_COM CLASS(#PRIM_GPBX) NAME(#MAIL_LIST_GROUP) CAPTION('Currently Selected Emails') DISPLAYPOSITION(1) HEIGHT(224) LAYOUTMANAGER(#ATLM_4) LEFT(0) PARENT(#RIGHT_BOTTOM_PANEL) TABPOSITION(1) TABSTOP(False) TOP(4) WIDTH(282)
DEFINE_COM CLASS(#PRIM_SPLI) NAME(#SPLI_6) MANAGE(#MAIL_LIST_GROUP) PARENT(#SPLM_1)
DEFINE_COM CLASS(#PRIM_ATLI) NAME(#ATLI_5) ATTACHMENT(Center) MANAGE(#MAIL_LIST_GROUP) PARENT(#ATLM_1)
DEFINE_COM CLASS(#PRIM_ATLM) NAME(#ATLM_4) MARGINBOTTOM(4) MARGINLEFT(4) MARGINRIGHT(4) MARGINTOP(8)
DEFINE_COM CLASS(#PRIM_ATLI) NAME(#ATLI_6) ATTACHMENT(Center) MANAGE(#MAIL_LIST) PARENT(#ATLM_4)
DEFINE_COM CLASS(#PRIM_ATLI) NAME(#ATLI_2) ATTACHMENT(Center) MANAGE(#MAIL_LIST) PARENT(#ATLM_1)
DEFINE_COM CLASS(#PRIM_LVCL) NAME(#LVCL_3) CAPTION('Subject') CAPTIONTYPE(Caption) DISPLAYPOSITION(1) PARENT(#MAIL_LIST) SOURCE(#SYSVAR$AV) WIDTH(34)
DEFINE_COM CLASS(#PRIM_LVCL) NAME(#LVCL_4) CAPTION('From') CAPTIONTYPE(Caption) DISPLAYPOSITION(2) PARENT(#MAIL_LIST) SOURCE(#STD_TEXTL) WIDTH(34)
DEFINE_COM CLASS(#PRIM_LVCL) NAME(#LVCL_6) CAPTION('Received') CAPTIONTYPE(Caption) DISPLAYPOSITION(3) PARENT(#MAIL_LIST) SOURCE(#STD_DESC) WIDTH(20) WIDTHTYPE(Remainder)
DEFINE_COM CLASS(#PRIM_PANL) NAME(#CONNECT_SERVER_PANEL) DISPLAYPOSITION(9) HEIGHT(137) LEFT(300) PARENT(#TOP_PANEL) TABPOSITION(8) TABSTOP(False) TOP(8) WIDTH(213)
DEFINE_COM CLASS(#PRIM_PHBN) NAME(#CONNECT_SERVER) CAPTION('Connect to iSeries Server System') DISPLAYPOSITION(1) LEFT(16) PARENT(#CONNECT_SERVER_PANEL) TABPOSITION(1) TOP(32) WIDTH(172)
DEFINE_COM CLASS(#PRIM_PANL) NAME(#CONNECT_MAIL_PANEL) DISPLAYPOSITION(8) HEIGHT(129) LEFT(300) PARENT(#TOP_PANEL) TABPOSITION(10) TABSTOP(False) TOP(16) VISIBLE(False) WIDTH(205)
DEFINE_COM CLASS(#PRIM_PHBN) NAME(#CONNECT_MAIL) CAPTION('Connect to Email System') DISPLAYPOSITION(1) LEFT(16) PARENT(#CONNECT_MAIL_PANEL) TABPOSITION(1) TOP(48) WIDTH(172)
DEFINE_COM CLASS(#PRIM_PANL) NAME(#START_POLLING_PANEL) DISPLAYPOSITION(10) HEIGHT(129) LEFT(300) PARENT(#TOP_PANEL) TABPOSITION(9) TABSTOP(False) TOP(16) VISIBLE(False) WIDTH(205)
DEFINE_COM CLASS(#PRIM_PHBN) NAME(#START_POLLING) CAPTION('Start processing inbound emails') DISPLAYPOSITION(1) LEFT(16) PARENT(#START_POLLING_PANEL) TABPOSITION(1) TOP(66) WIDTH(172)
DEFINE_COM CLASS(#STD_NUM.Visual) NAME(#MAIL_POLLING_TIME) DISPLAYPOSITION(3) HEIGHT(19) LEFT(118) MARGINLEFT(0) PARENT(#START_POLLING_PANEL) TABPOSITION(3) TOP(95) WIDTH(37)
DEFINE_COM CLASS(#PRIM_LABL) NAME(#LABL_8) CAPTION('seconds') DISPLAYPOSITION(2) HEIGHT(19) LEFT(158) PARENT(#START_POLLING_PANEL) TABPOSITION(2) TABSTOP(False) TOP(97) WIDTH(48)
DEFINE_COM CLASS(#PRIM_LABL) NAME(#LABL_9) CAPTION('Check for email every') DISPLAYPOSITION(4) HEIGHT(19) LEFT(8) PARENT(#START_POLLING_PANEL) TABPOSITION(4) TABSTOP(False) TOP(97) WIDTH(106)

* The AS/400 Server connection object

DEFINE_COM CLASS(#VL_SAM003) NAME(#SERVER)

* Email session and messages objects

DEFINE_COM CLASS(#S_208XSO.MAPISession) NAME(#MAIL_SESSION) reference(*Dynamic)
DEFINE_COM CLASS(#S_208XMO.MAPIMessages) NAME(#INBOUND_MAIL) reference(*Dynamic)
DEFINE_COM CLASS(#S_208XMO.MAPIMessages) NAME(#OUTBOUND_MAIL) reference(*Dynamic)

* The Email polling timer

DEFINE_COM CLASS(#PRIM_TIMR) NAME(#MAIL_POLLING_TIMER) INTERVAL(0)

* The MS-Word document handler

DEFINE_COM CLASS(#S_208RMW) NAME(#MS_WORD) DISPLAYPOSITION(2) PARENT(#COM_OWNER) TABPOSITION(2) VISIBLE(False)

* The MS-Excel document handler

DEFINE_COM CLASS(#S_208RME) NAME(#MS_EXCEL) PARENT(#COM_OWNER) VISIBLE(False)

* Lists used to store names and values extracted from MS-Word or MS-Excel documents

Def_list #List01 (#S_208Name #S_208Inst #S_208AVal #S_208NVal) Type(*Working) Entrys(100)
Def_list #List02 (#S_208Name #S_208Inst #S_208AVal #S_208NVal) Type(*Working) Entrys(100)
Def_list #List03 (#S_208Name #S_208Inst #S_208AVal #S_208NVal) Type(*Working) Entrys(100)
Def_list #List04 (#S_208Name #S_208Inst #S_208AVal #S_208NVal) Type(*Working) Entrys(100)
Def_list #List05 (#S_208Name #S_208Inst #S_208AVal #S_208NVal) Type(*Working) Entrys(100)

* List used to get messages back from the server

Define #MessCount Reffld(#ListCount)
Def_List Name(#MESSAGES) Fields(#S_208MSG) Counter(#MESSCOUNT) Type(*WORKING) Entrys(9999)

* Lists used to get spool file details back from the server

DEF_LIST NAME(#SPOOL01) FIELDS(#S_208MSG) TYPE(*WORKING) ENTRYS(240)
DEF_LIST NAME(#SPOOL02) FIELDS(#S_208MSG) TYPE(*WORKING) ENTRYS(240)
DEF_LIST NAME(#SPOOL03) FIELDS(#S_208MSG) TYPE(*WORKING) ENTRYS(240)
DEF_LIST NAME(#SPOOL04) FIELDS(#S_208MSG) TYPE(*WORKING) ENTRYS(240)

* Global flag to store the name of function to be called on the
* the server system to process a document has been found in the
* data extracted from a MS-Word or MS-Excel document

DEFINE_COM CLASS(#STD_OBJ) NAME(#RDML_FUNCTION)

* The event that signals that some documentation information has been found
* (also see S_208RMW and S_208RME that also signal this message)

Define_Evt InformationFound
Define_Map *input #S_208Name #WithName
Define_Map *input #S_208AVAL #WithValue

* ===============================
* Handle main form initialization
* ===============================

EVTROUTINE handling(#com_owner.Initialize)

* Set up the form caption and initalize other variables

SET #com_owner caption(*component_desc)

* Log the form start up to the event log

Invoke #Com_Owner.Log EventText(*component_desc) EventText2('started')

* Create and initialize the MAPI email session

Set_Ref #MAIL_SESSION (*Create_as #S_208XSO.MAPISession)
Set #MAIL_SESSION Parent(#Com_Owner)
Invoke #Mail_Session.Realize

* Create and initialize the MAPI email message handler for inbound mail

Set_Ref #INBOUND_MAIL (*Create_as #S_208XMO.MAPIMessages)
Set #Inbound_Mail Parent(#Com_Owner)
Invoke #Inbound_Mail.Realize

* Create and initialize the MAPI email message handler for outbound mail

Set_Ref #OUTBOUND_MAIL (*Create_as #S_208XMO.MAPIMessages)
Set #Outbound_Mail Parent(#Com_Owner)
Invoke #Outbound_Mail.Realize

ENDROUTINE

* ========================
* Handle main form closing
* ========================

EVTROUTINE handling(#com_owner.Closing)

* Disconnect the AS/400 server

Invoke #Server.uDisconnect

* Shutdown the MS-Word document handler

Invoke #MS_Word.Shutdown

* Shutdown the MS-Excel document handler

Invoke #MS_Excel.Shutdown

* Disconnect from the mail server

If '#Mail_Session.SessionId *ne 0'
Invoke #Mail_Session.SignOff
Endif

* Destroy all of the MAPI email objects

Invoke #OutBound_Mail.unRealize
Invoke #InBound_Mail.unRealize
Invoke #Mail_Session.unRealize

Set_Ref #OutBound_Mail *null
Set_Ref #InBound_Mail *null
Set_Ref #Mail_Session *null

ENDROUTINE

* ================================================
* Handle a request to connect to the AS/400 server
* ================================================

EVTROUTINE HANDLING(#CONNECT_SERVER.Click)

Invoke #Com_Owner.Log EventText('Connecting to iSeries server system')

INVOKE METHOD(#SERVER.uConnectModal)

ENDROUTINE

* =====================================================================
* Handle a server connection creation signalled by #SERVER (#VL_SAM003)
* =====================================================================

EVTROUTINE HANDLING(#SERVER.uConnectionCreated)

Invoke #Com_Owner.Log EventText('Now connected to iSeries server system')

* Make the connect to AS/400 server panel invisible

Set #Connect_Server_panel Visible(False)

* Now make the connect to email server panel visible

Set #Connect_Mail_panel Visible(True)

ENDROUTINE

* ===================================================
* Handle a request to connect to the to email system
* ===================================================

EVTROUTINE HANDLING(#CONNECT_Mail.Click)

* Logon / Connect to the email system

Invoke #Com_Owner.Log EventText('Signing on to email system')

Set #Mail_Session LogonUI(True)

Invoke #Mail_Session.Signon

* Link the mail inbound and outbound email sessions to the connection

Set #InBound_Mail SessionId(#Mail_Session.SessionId)

Set #OutBound_Mail SessionId(#Mail_Session.SessionId)

Invoke #Com_Owner.Log EventText('Signed on to email system')

* Make the connect to email server panel invisible

Set #Connect_Mail_panel Visible(False)

* Make the start processing email panel visible
* and set a default value for the polling time

Set #Start_Polling_panel Visible(True)

Set #Mail_Polling_Time Value(30)

ENDROUTINE

* ========================================================
* Check that the email pollng time specified is "sensible"
* ========================================================

EVTROUTINE HANDLING(#Mail_Polling_Time.LostFocus) OPTIONS(*NOCLEARMESSAGES *NOCLEARERRORS)

Change #Std_Num #Mail_Polling_Time.Value

* If less then 10 set to 10, if greater than 600 set to 600

Case #Std_Num
When '< 10'
Set #Mail_Polling_Time Value(10)
When '> 600'
Set #Mail_Polling_Time Value(600)
EndCase

ENDROUTINE

* =============================================================
* Handle a request to start polling/checking for email messages
* =============================================================

EVTROUTINE HANDLING(#Start_Polling.Click)

* Make the start processing email panel invisible

Set #Start_Polling_Panel Visible(False)

* Make all the connection details and instructions at the top
* of the main form disappear

Set #Top_Panel Visible(False)

* Start the mail polling timer running (see #Mail_Polling_Timer.Tick)

Set #Mail_Polling_Timer Interval(1)

ENDROUTINE

* =================================================
* Handle a tick of the mail polling timer
* (ie: It's time to check for newly arrived email)
* =================================================

EVTROUTINE HANDLING(#Mail_Polling_Timer.Tick) OPTIONS(*NOCLEARMESSAGES *NOCLEARERRORS)
Define #A_Limit Reffld(#Std_Num) Desc('Count of inbound emails')
Define #A_Index Reffld(#Std_Num) Desc('Loop index for inbound messages loop')
Define #MsgIndex Reffld(#Std_Num) Desc('Index to current inbound email')

* Stop the timer

Set #Mail_Polling_Timer Interval(0)

* Log a starting message

Invoke #Com_Owner.Log EventText('Checking for new emails')

* Fetch an updated email list from the Inbox

Invoke #InBound_Mail.Fetch

* Loop through all email messages currently in the InBox

Clr_List #Mail_List

Change #A_Limit #InBound_Mail.MsgCount
Begin_Loop from(1) to(#A_Limit) Using(#A_Index)
Change #MsgIndex '#A_Index - 1'

* Set the index to the current email message details

Set #InBound_Mail MsgIndex(#MsgIndex)

* Skip this message if it's already been read or if it has no attachments

Continue '(#InBound_Mail.MsgRead = True) or (#InBound_Mail.AttachmentCount <= 0)'

* Assemble the message details to place into the visible list

Change #SysVar$Av #InBound_Mail.MsgSubject
Change #Std_TextL #InBound_Mail.MsgOrigDisplayName
Change #Std_Desc #InBound_Mail.MsgDateReceived

* Add an entry to the mail list visible on the mail form

Add_Entry #Mail_List

* Loop around and process the next message

End_Loop

* Log a completion message

Invoke #Com_Owner.Log EventText('Finished checking for new emails')

* Update the display of the mail details on the main form so that they become immediately visible

Invoke #Mail_List_Group.UpdateDisplay

* Now do a second pass through the messages and pick out all unread
* messages that have attachments. These are eligible for processing

Invoke #Com_Owner.Log EventText('Now checking for unread emails with attachments')

Change #A_Limit #InBound_Mail.MsgCount
Begin_Loop from(#A_Limit) to(1) Using(#A_Index) Step(-1)
Change #MsgIndex '#A_Index - 1'

* Set the index to the current email message details

Set #InBound_Mail MsgIndex(#MsgIndex)

* Skip this message if it's already been read or if it has no attachments

Continue '(#InBound_Mail.MsgRead = True) or (#InBound_Mail.AttachmentCount <= 0)'

* We now have a message to be handled, invoke HandleAttachments to check out any attachments that this email may have

Invoke #Com_Owner.HandleAttachments

* Loop around and process the next email message

End_Loop

Invoke #Com_Owner.Log EventText('Finished checking for unread emails with attachments')

* Now restart the timer

Change #Std_Num '#Mail_Polling_Time.Value * 1000'

Set #Mail_Polling_Timer Interval(#Std_Num)

* Finished .... we'll now wait for the next tick of the timer and do it all again

ENDROUTINE

* ====================================================
* Handle all attachments in the current email message
* ====================================================

MthRoutine HandleAttachments

Define #B_Limit Reffld(#Std_Num) Desc('Loop Limit')
Define #B_Index Reffld(#Std_Num) Desc('Loop Index')
Define #AtchIndex Reffld(#Std_Num) Desc('Current Attachment Index')
Define #RetCode2 *char 2 Desc('Standard char(2) LANSA return code')

* Log start

Invoke #Com_Owner.Log EventText('Processing' ) EventText2(#InBound_Mail.MsgSubject) EventText3('from') EventText4(#InBound_Mail.MsgOrigDisplayName)

* Loop through all the attachments in the current email message

Change #B_Limit #InBound_Mail.AttachmentCount
Begin_Loop from(1) to(#B_Limit) Using(#B_Index)

Change #AtchIndex '#B_Index - 1'

Set #InBound_Mail AttachmentIndex(#AtchIndex)

* Invoke HandleDocument to handle a single document attached to the current email message

Invoke #Com_Owner.HandleDocument DocumentName(#InBound_Mail.AttachmentName) DocumentPathName(#InBound_Mail.AttachmentPathName)

End_Loop

* Log end

Invoke #Com_Owner.Log EventText('Finished processing' ) EventText2(#InBound_Mail.MsgSubject) EventText3('from') EventText4(#InBound_Mail.MsgOrigDisplayName)

Endroutine

* ===============================================================
* Handle a single attached document in the current email message
* ===============================================================

MthRoutine HandleDocument
Define_Map *input #SysVar$Av #DocumentName
Define_Map *input #SysVar$Av #DocumentPathName

Define #Position Type(*Dec) Length(3) decimals(0) Desc('Scan Position')
Define #Temp_File Reffld(#SysVar$av) Desc('Temporary File Name')
Def_Cond *Found '#Position > 0'

* Log attachment processing start

Invoke #Com_Owner.Log EventText('Processing attachment' ) EventText2(#DocumentName.Value) EventText3('in') EventText4(#DocumentPathName.Value)

* Clear all the storage areas and lists used betwene the client (this component)
* and the server (RDML function SET208H).

* List01 -> List05 are the values extracted from the MS-Word or MS-Excel document

Change #ListCount 0
Clr_List #List01
Clr_List #List02
Clr_List #List03
Clr_List #List04
Clr_List #List05

* Messages is the list of messages returned by the AS/400 server after
* the document has been processed. Ultimately Messages is used to form the
* text of the attachment file that is sent back to the email sender.

Clr_List #Messages

* Spool01 -> Spool04 are any spool file details that have been sent back
* by the AS/400 server. These are added to the Messages list and also
* sent back to the email sender. See RDML function SET208Q for an example
* of a function that prints a report on the server and sends the spool file
* details back in lists Spool01 -> Spool04

Clr_List #Spool01
Clr_List #Spool02
Clr_List #Spool03
Clr_List #Spool04

* Set the name of the RDML function to be called to handle this document
* to blanks to indicate that it has not been found in the document data (yet).

Set #RDML_FUNCTION Value(*Blanks)

* Now see if this attachment is a MS-Word document

Use ScanString (#DocumentName.Value '.DOC' 1 '1' '1') To_Get(#Position)

* If it is a MS-Word document invoke #MS_Word.ExtractInformation to extract all the
* book mark details from the document. The details are signalled back to this
* component by "InformationFound" events issued by #MS_Word.ExtractInformation.

If *Found

Invoke #Com_Owner.Log EventText('Found MS-Word document' ) EventText2(#DocumentName.Value)

Invoke #MS_Word.ExtractInformation FromDocument(#DocumentPathName.Value)

Else

* If not a MS-Word document, see if this attachment is a MS-Excel document

Use ScanString (#DocumentName.Value '.XLS' 1 '1' '1') To_Get(#Position)

* If it is a MS-Word document invoke #MS_Excel.ExtractInformation to extract all the
* speadsheet cell details from the document. The details are signalled back to this
* component by "InformationFound" events issued by #MS_Excel.ExtractInformation.

If *Found

Invoke #Com_Owner.Log EventText('Found MS-Excel document' ) EventText2(#DocumentName.Value)

Invoke #MS_Excel.ExtractInformation FromDocument(#DocumentPathName.Value)

Endif

Endif

* If something was added to one of the lists by one of the information
* extractors (ie: #MS_Word.ExtractInformation or #MS_Excel.ExtractInformation)
* we need to place a call to the AS/400 server application to process the
* extracted details ....

If '#ListCount > 0'

* If the name of the RDML function to be used on the server to process
* the information extracted from the document has not been found in
* the document set a default value from the first 7 characters of the
* attachment file name .....

If '#RDML_Function.Value = *Blanks'
Define #TmpChar07 *char 7
Change #TmpChar07 #DocumentName.Value
Signal InformationFound WithName(RDML_FUNCTION) WithValue(#TmpChar07)
Endif

* Log an event identifying the RDML function that will used to handle the document on the server system

Invoke #Com_Owner.Log EventText('RDML function' ) EventText2(#RDML_Function.Value) EventText3('will be used to handle document') EventText4(#DocumentName.Value)

* Do the call to the remote procedure. Call RDML function SET208H which will manage details of calling the handling RDML function specified in #RDML_Function.Value

USE CALL_SERVER_FUNCTION WITH_ARGS(*SSERVER_SSN SET208H N Y #LIST01 #LIST02 #LIST03 #LIST04 #LIST05 #Messages #Spool01 #Spool02 #Spool03 #Spool04) TO_GET(#RetCode2)

* If the call to RDML function SET208H failed, log an error into the event log

If '#RetCode2 *ne OK'
Invoke #Com_Owner.Log EventText('***ERROR*** Call to server message handler failed.' )
Endif

* Now collect any messages on the current message queue and add them to the message list and then clear the message queue

Use Get_Message To_Get(#RetCode2 #S_208Msg)
Dowhile '(#MessCount < 9999) and (#RetCode2 = OK)'
Add_Entry #Messages
Use Get_Message To_Get(#RetCode2 #S_208Msg)
EndWhile

Use Clr_Messages

* Now collect any returned spool file lines and place them into the message list as well

SelectList #Spool01
Add_Entry #Messages
EndSelect
SelectList #Spool02
Add_Entry #Messages
EndSelect
SelectList #Spool03
Add_Entry #Messages
EndSelect
SelectList #Spool04
Add_Entry #Messages
EndSelect

* Now transform the entire messages list into a temporary flat file (name is in #Temp_File)

Use tConcat (*Temp_Dir 'S_208FMF_Reply.txt') (#Temp_File)
USE BUILTIN(TRANSFORM_LIST) WITH_ARGS(#Messages #Temp_File C B T) TO_GET(#RetCode2)

* If the TRANSFORM_LIST operation failed, log an error to the event
* log and blank out the temporary file name so that it will not be
* sent as an attachment later

If '#RetCode2 *ne OK'
Invoke #Com_Owner.Log EventText('***ERROR*** Attempt to save temporary file failed.' )
Change #Temp_File *Blanks
Endif

* Now assemble the reply email

Invoke #OutBound_Mail.Compose

* Set up the addressing details

Set #OutBound_Mail RecipDisplayName(#InBound_Mail.MsgOrigDisplayName)
Set #OutBound_Mail RecipAddress(#InBound_Mail.MsgOrigAddress)
Set #OutBound_Mail AddressResolveUI(False)

* Set up the subject

Use bConcat ('Automatic Response to ->' #InBound_Mail.MsgSubject) (#SysVar$av)
Set #OutBound_Mail MsgSubJect(#SysVar$av)

* Set up the message text body

Set #OutBound_Mail MsgNoteText('Please read the attachment for response details.')

* Add the temporary messages file (if it was saved okay) to the
* email as an attachment

If '#Temp_File *ne *Blanks'
Set #OutBound_Mail AttachmentPathName(#Temp_File)
Endif

* Log an event indicating that email is about to be sent

Invoke #Com_Owner.Log EventText('Sending reply email to' ) EventText2(#OutBound_Mail.RecipDisplayName)

* Send the email message back to the original sender

Invoke #OutBound_Mail.Send vDialog(0)

Endif

* Log document processing end

Invoke #Com_Owner.Log EventText('Finished processing attachment' ) EventText2(#DocumentName.Value) EventText3('in') EventText4(#DocumentPathName.Value)

Endroutine

* ========================================================================
* Handle extracted information coming back from this component itself, the
* MS-Word information extractor or the MS-Excel information extractor
* ========================================================================

EVTROUTINE HANDLING(#COM_Owner.InformationFound #MS_Word.InformationFound #MS_Excel.InformationFound) OPTIONS(*NOCLEARMESSAGES *NOCLEARERRORS) WithName(#WithName) WithValue(#WithValue)

Define #Pos *Dec 3 0
Define #Int *Dec 15 0
Define #Dec *Dec 9 9
Define #LastPos Reffld(#pos)
Define #TWithName Reffld(#S_208Name)
Define #RetCode *char 1

* Set up the default values for the entry to be stored in the lists
* that will be eventually passed to the server function SET208H

* #S_208NAME - the NAME (most commonly a MS-Word bookmark or CELL_rrrrrrr_ccccccc)

Change #S_208Name #WithName.value
Use UpperCase (#S_208Name) (#S_208Name)

* #S_208INST - the INSTANCE of the name

Change #S_208Inst 1

* #S_208AVAL - the ALPHANUMERIC value

Change #S_208AVal #WithValue.value

* #S_208NVAL - the NUMERIC value (if a conversion is possible)

Change (#Int #Dec) *Null
Use CHECKNUMERIC WITH_ARGS(#S_208AVal 15 9) TO_GET(#Int #Dec #RetCode)
Change #S_208NVal '#Int + #Dec'

* Now see if the name ends in an instance number (ie: the name is in
* the format NAME_nnnn) and if it does, extract the instance number
* and remove the instance number from the name. Thus the name
* EMPNO_56 changes #S208Inst to 56 and #S_208Name to EMPNO.
* Likewise the the name CELL_000007_00005 would be reduced
* to name CELL_000007 and instance number 5

Change #Pos 1
Change #LastPos 0

Begin_Loop
Use ScanString WITH_ARGS(#S_208Name '_' #Pos) TO_GET(#Pos)
Leave '#Pos <= 0'
Leave '#Pos >= 32'
Change #LastPos #Pos
Change #Pos '#Pos + 1'
End_Loop

If '#LastPos > 0'
Change #TWithName *Blanks
Substring (#S_208Name #LastPos) (#TWithName)
Change #Int *Null
Use CHECKNUMERIC WITH_ARGS(#TWithName 7 0 '_') TO_GET(#Int #Dec #RetCode)
If '(#RetCode = Y) and (#Int > 0)'
Change #S_208Inst #Int
Substring (#Blank) (#S_208Name #LastPos *End)
Endif
Endif

* We now should have the #S208Name, #S208Inst, #S_208Aval and #S_208NVal
* values finalized ... so add an entry to appropriate storage list.
*
* Five lists (List01 -> List05) are used here to avoid any one list being
* more than 32,000 bytes long when it is passed to the server function
* SET208H. Logically they can be thought of as a single list.

Case #ListCount
When '< 100'
Add_Entry #List01
When '< 200'
Add_Entry #List02
When '< 300'
Add_Entry #List03
When '< 400'
Add_Entry #List04
When '< 500'
Add_Entry #List05
Otherwise
Invoke #Com_Owner.Log EventText('***ERROR*** List overflow. Data ignored.') EventText2(#S_208AVal)
EndCase

* Keep a count of the total number of list entries added

Change #ListCount '#ListCount + 1'

* If the name just processed is "RDML_FUNCTION" then save the
* value. This name is used by method routine "HandleDocument" to
* decide whether it should add a default function name to the
* list of document values.

If '#S_208Name = RDML_FUNCTION'
Set #RDML_FUNCTION Value(#S_208AVal)
Endif

Endroutine

* =====================================
* Log an Event to the visible event log
* =====================================

MthRoutine Log
Define_Map *input #SysVar$Av #EventText
Define_Map *input #SysVar$Av #EventText2 Mandatory(' ')
Define_Map *input #SysVar$Av #EventText3 Mandatory(' ')
Define_Map *input #SysVar$Av #EventText4 Mandatory(' ')

* Clear the log if it has more than 200 message in it

If '#Event_Log.Entries > 200'
Clr_List #Event_Log
Endif

* Concatenate the message parts together

Use bConcat (#EventText.Value #EventText2.Value #EventText3.Value #EventText4.Value) (#SysVar$Av)

* Set the time and add an entry to the event log

Change #Time *Time

Add_Entry #Event_Log

Set #Event_Log.CurrentItem EnsureVisible(True)

* Update the display so that the event log message appears instantly

Invoke #Event_Log_Group.UpdateDisplay

Endroutine

END_COM