Additional Blogs by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member

This 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.

INFOTYPES0000, 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.

   DATANUMBER        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.

  IF SY-SUBRC <> 0.

* Implement suitable error handling here

   ENDIF.

*  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.

2 Comments