Email HR Payslips as PDF attachment - HRFORMS
发表人 Pavan Vudaga 位置 Pavan Vudaga's Blog 打开 2012-7-6 6:16:50This blog describes one of the options to email HR payslips as pdf attachments when HRFORMS are using smartforms. When a new HR form with form name "xxxxxx" is created with the smartform layout editor, a new print program /1PYXXFO/xxxxxx_PRNT is generated automatically. A separate program is required to email the payslips. This program can also send multiple emails.
Note: The print program /1PYXXFO/xxxxxx_PRNT can also be used to create a transaction code to re-print the payslips.
The new program must have have similar selection screen to the print program. So, when the new program is created, use the same logical database used in the print program. If there is a HR report category used in the print program, use the same in the new program as per the below screenshot. Copy the selection screen declarations(similar to the below sample code) from the print program into the new program.This will ensure that the selection screen is similar to the print program.
INFOTYPES: 0000, 0001, 0008.
TABLES PERNR. NODES PERSON. NODES PERAS. NODES GROUP. *data for sel screen: table for reacting to screen events TABLES SSCRFIELDS. *--------------------------------------------------------------------* *----------------------- selection screen --------------------------* *--------------------------------------------------------------------* SELECTION-SCREEN BEGIN OF BLOCK OPTSELFLDS WITH FRAME TITLE TEXT-001. PARAMETERS P_IPVIEW TYPE INPERVIEW NO-DISPLAY DEFAULT 'X'. PARAMETERS P_ADDRET TYPE H99_ADD_RETROES AS LISTBOX VISIBLE LENGTH 30 DEFAULT 'X'. PARAMETERS P_ARCTOO TYPE ARCH_TOO NO-DISPLAY. PARAMETERS P_SIMCE TYPE H99_SIMCE NO-DISPLAY. SELECTION-SCREEN END OF BLOCK OPTSELFLDS. SELECTION-SCREEN BEGIN OF BLOCK SELOTHER WITH FRAME TITLE TEXT-002. PARAMETERS: P_SFPEE TYPE HRF_SFPER DEFAULT 1 MODIF ID SFP VALUE CHECK. "no of employees each form PARAMETERS: P_SFPER TYPE C NO-DISPLAY DEFAULT 1. "1 form each employee\ "obsolete but still here for compatibility with old variants PARAMETERS: P_NOSTAT TYPE HRF_NOSTAT DEFAULT 'X'. "display statistics y/n PARAMETERS: P_TOOAR TYPE HRF_TOOAR AS LISTBOX VISIBLE LENGTH 30 DEFAULT SPACE USER-COMMAND OAR, "optical archiving y/n P_PLANG TYPE HRF_PLANG DEFAULT SPACE USER-COMMAND LANG, "form in employee language y/n P_INFTBE TYPE HRF_ALLINFTRECORDS DEFAULT SPACE MODIF ID IBE. "only read IT records between BEGDA and ENDDA y/n *hidden parameters for report calls from other applications PARAMETERS: P_POPUP TYPE XFELD NO-DISPLAY DEFAULT ''. "print popup switch on/off SELECTION-SCREEN END OF BLOCK SELOTHER.
AT SELECTION-SCREEN OUTPUT. * Checkboxes are interlinked: optical adjustment LOOP AT SCREEN. IF SCREEN-NAME EQ 'P_PLANG'. IF P_SFPEE EQ 0. SCREEN-INPUT = 0. ELSE. SCREEN-INPUT = 1. ENDIF. MODIFY SCREEN. ENDIF. IF SCREEN-GROUP1 EQ 'SFP'. SCREEN-ACTIVE = 0. MODIFY SCREEN. ENDIF. IF SCREEN-GROUP1 EQ 'IBE'. SCREEN-ACTIVE = 0. MODIFY SCREEN. ENDIF. ENDLOOP. |
Next, process each employee record one at a time based on the selection screen parameters. Execute the print program /1PYXXFO/xxxxxx_PRNT in a background job to generate a new spool request. This can be done using the 'JOB_OPEN' and 'JOB_CLOSE' function modules. The F.Ms use unique job name and job number, which can be used later to identify the spool request generated by the backgound job. When calling the print program in a background job, pass one employee number at a time to the print program and rest of the selection parameters as entered by the user. Set the parameters to execute the background job immediately and to generate a new spool id.
Execute the Payslip program for a single employee in backgound |
---|
START-OF-SELECTION.
DATA: LS_PRIPAR TYPE PRI_PARAMS. DATA: NUMBER TYPE TBTCJOB-JOBCOUNT, NAME TYPE TBTCJOB-JOBNAME. DATA: LT_ALL_PERNR TYPE PCCET_PNP_TAB_PERSON_PERNR, LS_ALL_PERNR TYPE PCCE_PNP_PERSON_PERNR, LT_PNPPERNR TYPE RANGE OF PERNR-PERNR, LS_PNPPERNR LIKE LINE OF PNPPERNR.
CLEAR P_POPUP. P_SFPER = 1. P_SFPEE = 1. P_PLANG = 'X'. CALL FUNCTION 'GET_PRINT_PARAMETERS' EXPORTING NO_DIALOG = 'X' IMPORTING OUT_PARAMETERS = LS_PRIPAR EXCEPTIONS ARCHIVE_INFO_NOT_FOUND = 1 INVALID_PRINT_PARAMS = 2 INVALID_ARCHIVE_PARAMS = 3 OTHERS = 4. LS_PRIPAR-PRIMM = 'X'. LS_PRIPAR-PDEST = 'ZCPF'. LS_PRIPAR-PRNEW = 'X'.
GET PERSON.
CLEAR: LT_ALL_PERNR[], LS_ALL_PERNR,NAME, LT_PNPPERNR[], LS_PNPPERNR, NUMBER. LT_ALL_PERNR[] = PERSON-ALL_PERNRS[]. SORT LT_ALL_PERNR BY PERNR. DELETE ADJACENT DUPLICATES FROM LT_ALL_PERNR COMPARING PERNR. LOOP AT LT_ALL_PERNR INTO LS_ALL_PERNR. LS_PNPPERNR-SIGN = 'I'. LS_PNPPERNR-OPTION = 'EQ'. LS_PNPPERNR-LOW = LS_ALL_PERNR-PERNR. APPEND LS_PNPPERNR TO LT_PNPPERNR. ENDLOOP. CONCATENATE 'Payslip_Spool_' LS_ALL_PERNR-PERNR INTO NAME.
CALL FUNCTION 'JOB_OPEN' EXPORTING JOBNAME = NAME IMPORTING JOBCOUNT = NUMBER EXCEPTIONS CANT_CREATE_JOB = 1 INVALID_JOB_DATA = 2 JOBNAME_MISSING = 3 OTHERS = 4. CHECK SY-SUBRC = 0.
SUBMIT /1PYXXFO/ZPAYSLIP_CHINA_PRNT AND RETURN WITH P_ADDRET = P_ADDRET WITH P_INFTBE = P_INFTBE WITH P_NOSTAT = P_NOSTAT WITH P_PLANG = P_PLANG WITH P_SFPEE = P_SFPEE WITH P_SFPER = P_SFPER WITH P_TOOAR = P_TOOAR WITH P_POPUP = P_POPUP WITH PNPPERNR IN LT_PNPPERNR[] WITH PNPABKRS IN PNPABKRS[] WITH PN-BEGDA EQ PN-BEGDA WITH PN-ENDDA EQ PN-ENDDA WITH PN-BEGPS EQ PN-BEGPS WITH PN-ENDPS EQ PN-ENDPS WITH PN-PABRP EQ PN-PABRP WITH PN-PABRJ EQ PN-PABRJ WITH PN-PERMO EQ PN-PERMO WITH PNPXABKR EQ PNPXABKR VIA JOB NAME NUMBER NUMBER TO SAP-SPOOL SPOOL PARAMETERS LS_PRIPAR WITHOUT SPOOL DYNPRO.
CALL FUNCTION 'JOB_CLOSE' EXPORTING JOBCOUNT = NUMBER JOBNAME = NAME STRTIMMED = 'X' EXCEPTIONS CANT_START_IMMEDIATE = 1 INVALID_STARTDATE = 2 JOBNAME_MISSING = 3 JOB_CLOSE_FAILED = 4 JOB_NOSTEPS = 5 JOB_NOTEX = 6 LOCK_FAILED = 7 OTHERS = 8. CHECK SY-SUBRC = 0. WAIT UP TO 4 SECONDS." For the background prog to finish execution and generate the spool
PERFORM SEND_PERNR_PAYSLIP_EMAIL USING LS_ALL_PERNR-PERNR NUMBER NAME. |
Insert the statement to wait for 4 seconds or even less for the background job to finish execution. A new spool request will be created every time the background job is executed successfully. The subroutine SEND_PERNR_PAYSLIP_EMAIL will handle the process of emailing the payslip to the employee email address. First, the employee email address is read from the employee master data, using the "HR_READ_INFORTYPE" function module. Next, using the job name and job number the spool id generated by the background job is retrieved using the function module "BP_JOB_READ".
Note: More than one spool may be generated. Additional logic must be used to distinguish the spool id related to the employee payslip.
Convert the ABAP spool OTF to PDF |
---|
FORM SEND_PERNR_PAYSLIP_EMAIL USING IV_PERNR TYPE PERNR-PERNR IV_JOBCOUNT TYPE TBTCJOB-JOBCOUNT IV_JOBNAME TYPE TBTCJOB-JOBNAME.
DATA: LV_BIN_FILE TYPE XSTRING, LS_DOC_DATA TYPE SODOCCHGI1, LT_PACK_LIST TYPE TABLE OF SOPCKLSTI1, LS_PACK_LIST LIKE LINE OF LT_PACK_LIST, LT_ATTACH TYPE TABLE OF SOLISTI1, LS_ATTACH LIKE LINE OF LT_ATTACH, LT_BODY TYPE TABLE OF SOLISTI1, LS_BODY LIKE LINE OF LT_BODY, LT_RECEIVERS TYPE TABLE OF SOMLRECI1, LS_RECEIVERS LIKE LINE OF LT_RECEIVERS, LT_LINES TYPE TABLE OF TLINE, LT_PDF_LINES TYPE TABLE OF TLINE, LS_LINE LIKE LINE OF LT_LINES, LV_EMAIL TYPE ADR6-SMTP_ADDR, LV_SENDER TYPE SOEXTRECI1-RECEIVER, LV_SENDER_TYP TYPE SOEXTRECI1-ADR_TYP, LV_SENT_ALL TYPE SONV-FLAG, LV_PDF_LINES TYPE I, LV_TDNAME TYPE THEAD-TDNAME VALUE 'ZHR_PAYSLIP_BODY', LV_BODY_LINES TYPE I, LT_SPOOL TYPE TABLE OF BAPIXMSPOOLID, LS_SPOOL LIKE LINE OF LT_SPOOL, LT_P0105 TYPE TABLE OF P0105, LS_P0105 LIKE LINE OF LT_P0105, LT_P0002 TYPE TABLE OF P0002, LS_P0002 LIKE LINE OF LT_P0002, LV_GBDAT TYPE P0002-GBDAT, LV_SPOOL_CH TYPE TSP01_SP0R-RQID_CHAR.
CHECK IV_PERNR IS NOT INITIAL. CALL FUNCTION 'HR_READ_INFOTYPE' EXPORTING PERNR = IV_PERNR INFTY = '0105' BYPASS_BUFFER = 'X' TABLES INFTY_TAB = LT_P0105 EXCEPTIONS INFTY_NOT_FOUND = 1 OTHERS = 2. IF SY-SUBRC EQ 0. * SORT THE INTERNAL TABLE TO GET THE LATEST VALUE AND READ THE TABLE. SORT LT_P0105 BY BEGDA DESCENDING. READ TABLE LT_P0105 INTO LS_P0105 WITH KEY SUBTY = '0010'. IF LS_P0105-USRID_LONG NE ' '. LV_EMAIL = LS_P0105-USRID_LONG. "retrieving the mail id of the employee ELSE. " error message when mail id not found. ENDIF. ENDIF.
CALL FUNCTION 'BP_JOB_READ' EXPORTING JOB_READ_JOBCOUNT = IV_JOBCOUNT JOB_READ_JOBNAME = IV_JOBNAME JOB_READ_OPCODE = '36' TABLES SPOOL_ATTRIBUTES = LT_SPOOL EXCEPTIONS INVALID_OPCODE = 1 JOB_DOESNT_EXIST = 2 JOB_DOESNT_HAVE_STEPS = 3 OTHERS = 4. IF SY-SUBRC <> 0. * Implement suitable error handling here ENDIF.
READ TABLE LT_SPOOL INTO LS_SPOOL WITH KEY DOCTYP = 'SMART'. IF SY-SUBRC <> 0. * Implement suitable error handling here ENDIF.
CHECK LS_SPOOL-SPOOLID IS NOT INITIAL. CALL FUNCTION 'CONVERT_OTFSPOOLJOB_2_PDF' EXPORTING SRC_SPOOLID = LS_SPOOL-SPOOLID IMPORTING TABLES PDF = LT_PDF_LINES EXCEPTIONS ERR_NO_OTF_SPOOLJOB = 1 ERR_NO_SPOOLJOB = 2 ERR_NO_PERMISSION = 3 ERR_CONV_NOT_POSSIBLE = 4 ERR_BAD_DSTDEVICE = 5 USER_CANCELLED = 6 ERR_SPOOLERROR = 7 ERR_TEMSEERROR = 8 ERR_BTCJOB_OPEN_FAILED = 9 ERR_BTCJOB_SUBMIT_FAILED = 10 ERR_BTCJOB_CLOSE_FAILED = 11 OTHERS = 12. IF SY-SUBRC <> 0. * Implement suitable error handling here ENDIF. |
Convert the OTF spool into pdf format using the function module "CONVERT_OTFSPOOLJOB_2_PDF ". Once the pdf data is retrieved, then delete the background job and the spool. The pdf data is in the TLINE format. Convert the TLINE format to SOLISTI1. Email the pdf as an attachment using the function module "SO_DOCUMENT_SEND_API1".
Send PDF as an email attachment | |
---|---|
CHECK LT_PDF_LINES[] IS NOT INITIAL. CALL FUNCTION 'BP_JOB_DELETE' EXPORTING JOBCOUNT = IV_JOBCOUNT JOBNAME = IV_JOBNAME FORCEDMODE = 'X' * COMMITMODE = 'X' EXCEPTIONS CANT_DELETE_EVENT_ENTRY = 1 CANT_DELETE_JOB = 2 CANT_DELETE_JOBLOG = 3 CANT_DELETE_STEPS = 4 CANT_DELETE_TIME_ENTRY = 5 CANT_DERELEASE_SUCCESSOR = 6 CANT_ENQ_PREDECESSOR = 7 CANT_ENQ_SUCCESSOR = 8 CANT_ENQ_TBTCO_ENTRY = 9 CANT_UPDATE_PREDECESSOR = 10 CANT_UPDATE_SUCCESSOR = 11 COMMIT_FAILED = 12 JOBCOUNT_MISSING = 13 JOBNAME_MISSING = 14 JOB_DOES_NOT_EXIST = 15 JOB_IS_ALREADY_RUNNING = 16 NO_DELETE_AUTHORITY = 17 OTHERS = 18. IF SY-SUBRC <> 0. * Implement suitable error handling here ENDIF.
LV_SPOOL_CH = LS_SPOOL-SPOOLID. CALL FUNCTION 'RSPO_R_RDELETE_SPOOLREQ' EXPORTING SPOOLID = LV_SPOOL_CH.
CALL FUNCTION 'QCE1_CONVERT' TABLES T_SOURCE_TAB = LT_PDF_LINES T_TARGET_TAB = LT_ATTACH EXCEPTIONS CONVERT_NOT_POSSIBLE = 1 OTHERS = 2. IF SY-SUBRC <> 0. * Implement suitable error handling here ENDIF.
*--------------------------------------------------------- * EMAIL BODY TEXT STARTS HERE * Get the Body from the Standard Text CALL FUNCTION 'READ_TEXT' EXPORTING ID = 'ST' LANGUAGE = SY-LANGU NAME = LV_TDNAME OBJECT = 'TEXT' TABLES LINES = LT_LINES EXCEPTIONS ID = 1 LANGUAGE = 2 NAME = 3 NOT_FOUND = 4 OBJECT = 5 REFERENCE_CHECK = 6 WRONG_ACCESS_TO_ARCHIVE = 7 OTHERS = 8.
* Replace the place holders and add to body lines LOOP AT LT_LINES INTO LS_LINE. * REPLACE ALL OCCURRENCES OF '<LIFNR>' IN ls_line-tdline WITH gs_vendor-name1. LS_BODY-LINE = LS_LINE-TDLINE. APPEND LS_BODY TO LT_BODY. ENDLOOP. DESCRIBE TABLE LT_BODY LINES LV_BODY_LINES. DESCRIBE TABLE LT_ATTACH LINES LV_PDF_LINES. LS_DOC_DATA-OBJ_DESCR = 'Payslip'. LS_DOC_DATA-SENSITIVTY = 'F'. LS_DOC_DATA-DOC_SIZE = 255 * LV_BODY_LINES. CLEAR LS_PACK_LIST-TRANSF_BIN. LS_PACK_LIST-HEAD_START = 1. LS_PACK_LIST-HEAD_NUM = 0. LS_PACK_LIST-BODY_START = 1. LS_PACK_LIST-BODY_NUM = LV_BODY_LINES. LS_PACK_LIST-DOC_TYPE = 'RAW'. APPEND LS_PACK_LIST TO LT_PACK_LIST. CLEAR LS_PACK_LIST. CONCATENATE 'Payslip' IV_PERNR '.pdf' INTO LS_PACK_LIST-OBJ_DESCR SEPARATED BY SPACE. LS_PACK_LIST-TRANSF_BIN = ABAP_TRUE. LS_PACK_LIST-HEAD_START = 1. LS_PACK_LIST-HEAD_NUM = 1. LS_PACK_LIST-BODY_START = 1. LS_PACK_LIST-BODY_NUM = LV_PDF_LINES. LS_PACK_LIST-DOC_SIZE = 255 * LV_PDF_LINES. LS_PACK_LIST-DOC_TYPE = 'PDF'. LS_PACK_LIST-OBJ_NAME = 'Employee'. APPEND LS_PACK_LIST TO LT_PACK_LIST.
* Email adress / Efax adress LS_RECEIVERS-RECEIVER = LV_EMAIL. LS_RECEIVERS-EXPRESS = ABAP_TRUE. LS_RECEIVERS-REC_TYPE = 'U'. LS_RECEIVERS-NOTIF_DEL = ABAP_FALSE. " request delivery notification LS_RECEIVERS-NOTIF_NDEL = ABAP_TRUE. " request not delivered notification APPEND LS_RECEIVERS TO LT_RECEIVERS. LV_SENDER = SY-UNAME. LV_SENDER_TYP = 'B'. *--------------------------------------------------------- * Call the FM to send the actual email CALL FUNCTION 'SO_DOCUMENT_SEND_API1' EXPORTING DOCUMENT_DATA = LS_DOC_DATA PUT_IN_OUTBOX = ABAP_TRUE SENDER_ADDRESS = LV_SENDER SENDER_ADDRESS_TYPE = LV_SENDER_TYP * COMMIT_WORK = ABAP_TRUE IMPORTING SENT_TO_ALL = LV_SENT_ALL TABLES PACKING_LIST = LT_PACK_LIST CONTENTS_BIN = LT_ATTACH CONTENTS_TXT = LT_BODY RECEIVERS = LT_RECEIVERS EXCEPTIONS TOO_MANY_RECEIVERS = 1 DOCUMENT_NOT_SENT = 2 DOCUMENT_TYPE_NOT_EXIST = 3 OPERATION_NO_AUTHORIZATION = 4 PARAMETER_ERROR = 5 X_ERROR = 6 ENQUEUE_ERROR = 7 OTHERS = 8. IF SY-SUBRC <> 0. * Implement suitable error handling here ENDIF. ENDFORM. | |