ФОРМИРОВАНИЕ XML-ДОКУМЕНТОВ С ПОМОЩЬЮ ПРОГРАММ ПЕЧАТИ

СБИС САПЕР использует имеющиеся программы печати для формирование xml-документов. Данная методика позволяет избежать дублирования алгоритма формирования документа.

Алгоритм формирования электронного документа:

  1. СБИС САПЕР для каждого отправляемого документа SAP вызывает программу печати, указанную в настройках модуля. 

  2. Программа печати рассчитывает данные необходимые для печати.
  3. Перед вызовом формуляра, управление передается модулю СБИС САПЕР. Модуль проверяет, что инициирует вызов программы печати. Если инициатор вызова:
  • не САПЕР — модуль возвращает управление программе печати (все как обычно).
  • САПЕР —  модуль из подготовленных программой печати данных, выбирает нужные (по настройкам выгрузки) и формирует xml-документ. По окончании возвращает флаг, сигнализирующий о необходимости прервать программу печати.

Данный алгоритм работает на любом SAP, с любыми типами документов и отчетов (не зависит от функционала, реализованного SAP для журнала электронных счетов фактур из российского Add-on)

Доработка программ печати:

Прежде чем, вносить изменения в программу печати, сделайте ее копию. Рекомендуемый шаблон названия копии программы [ZSBIS_][Старое название программы]. Вместо копий программ печати можно использовать стандартные BADI в программах печати (например, J_3R_TORG12_BADI для программы печати накладной J_3RV_DELIV_PDF, J_3R_INV_BADI для программы печати фактуры J_3RV_INV_A).

В программу печати (или ее копию) добавьте вызов метода СБИС САПЕР, который завершает действия программы печати после формирования электронного документа.

Возможные доработки программ печати

  • В программе печати данные, необходимые для корректного формирования xml, должны храниться в отдельных полях. Например, в  программе печати данные о контрагенте содераться в одном поле, а в печатной форме документа название контрагента, его ИНН и КПП должны отображаться в одтельных строках.

Стандартные программы печати

Пример кода, который необходимо добавить перед вызовом формуляра в каждую программу печати.

TRY.
      DATA cx_root TYPE REF TO cx_root.
      DATA lv_not_print TYPE c VALUE ''.
      DATA cl_mapping TYPE REF TO /sbis/cl_mapping.
      CREATE OBJECT cl_mapping.
      CALL METHOD cl_mapping->calc_doc
        EXPORTING
          is_nast      = nast
        IMPORTING
          ev_not_print = lv_not_print.
      IF lv_not_print = 'X'.
        EXIT.
      ENDIF.
 
      data cx_core type ref to /sbis/cx_core.
      CATCH /sbis/cx_core INTO cx_core.
        DATA  lv_cur_prog  TYPE char255.
        DATA  lv_cur_form  TYPE char255.
        CALL METHOD /sbis/cl_core=>get_current_progname
          IMPORTING
            ev_prog_name = lv_cur_prog
            ev_form_name = lv_cur_form.
        FIELD-SYMBOLS: <fs_exc> TYPE /sbis/s_cx_core.
        ASSIGN ('(/SBIS/SAPLGF_PRINT_PROG)GS_EXC') TO <fs_exc>.
        IF  <fs_exc>    IS ASSIGNED.
          <fs_exc>-error_msg_ext    = cx_core->lv_error_msg_ext.
          <fs_exc>-error_msg_detail = cx_core->lv_error_msg_detail
                  && ` <= ` && lv_cur_prog && `->` && lv_cur_form.
        ENDIF.
        RAISE EXCEPTION TYPE /sbis/cx_core
          EXPORTING
            textid              = cx_core->textid
            lv_error_msg_ext    = cx_core->lv_error_msg_ext
            lv_error_msg_detail = cx_core->lv_error_msg_detail
            && ` <= ` && lv_cur_prog && `->` && lv_cur_form.
    ENDTRY.

Если в формулярах печатных форм есть логика расчета данных документа, то ее желательно перенести в программу печати.

Если у вас Z-программы печати, в которых используются подпрограммы, то вызов СБИС САПЕР чуть более сложный:

  • Сначала запускается подпрограмма ENTRY. Это оболочка для подпрограммы PROCESSING, передает код возврата, в ней изменения не понадобятся:
FORM entry USING return_code us_screen.                     "#EC CALLED
  CLEAR retcode.
  xscreen = us_screen.
  PERFORM processing USING us_screen.
  IF retcode NE 0.
    return_code = 1.
  ELSE.
    return_code = 0.
  ENDIF.
  CLEAR status.
ENDFORM.
  • Вызов печати обычно находится в теле подпрограммы PROCESSING.
FORM processing USING proc_screen.
  PERFORM checks.
  PERFORM init_data.
  PERFORM get_data.
  PERFORM print.
ENDFORM.
  • Поэтому до вызова печати (PRINT) необходимо вставить СБИС-код формирования электронных документов.
DATA  gv_not_print TYPE c .        " TENSOR SBIS EDO
 
FORM processing USING proc_screen.
 
  PERFORM checks.
  PERFORM init_data.
  PERFORM get_data.
  PERFORM sbis_edi.                " TENSOR SBIS EDO
  CHECK gv_not_print IS INITIAL.   " TENSOR SBIS EDO
  PERFORM print.
 
ENDFORM.
 
FORM sbis_edi .
* TENSOR SBIS EDO
  TRY.
      DATA cx_root TYPE REF TO cx_root.
      DATA cl_mapping TYPE REF TO /sbis/cl_mapping.
      CREATE OBJECT cl_mapping.
      CALL METHOD cl_mapping->calc_doc
        EXPORTING
          is_nast      = nast
        IMPORTING
          ev_not_print = gv_not_print.
 
      DATA cx_core TYPE REF TO /sbis/cx_core.
      CATCH /sbis/cx_core INTO cx_core.
        DATA  lv_cur_prog  TYPE char255.
        DATA  lv_cur_form  TYPE char255.
        CALL METHOD /sbis/cl_core=>get_current_progname
          IMPORTING
            ev_prog_name = lv_cur_prog
            ev_form_name = lv_cur_form.
        " exception проходит через прогр печати без текста!
        FIELD-SYMBOLS: <fs_exc> TYPE /sbis/s_cx_core.
        ASSIGN ('(/SBIS/SAPLGF_PRINT_PROG)GS_EXC') TO <fs_exc>.
        IF  <fs_exc>    IS ASSIGNED.
          <fs_exc>-error_msg_ext    = cx_core->lv_error_msg_ext.
          <fs_exc>-error_msg_detail = cx_core->lv_error_msg_detail
                                    && ` <= ` && lv_cur_prog && `->` && lv_cur_form.
        ENDIF.
        RAISE EXCEPTION TYPE /sbis/cx_core
          EXPORTING
            textid              = cx_core->textid
            lv_error_msg_ext    = cx_core->lv_error_msg_ext
            lv_error_msg_detail = cx_core->lv_error_msg_detail
                                  && ` <= ` && lv_cur_prog && `->` && lv_cur_form.
  ENDTRY.
ENDFORM.

Таким образом в зависимости от флага gv_not_print мы либо печатаем, либо выходим из программы с правильным кодом возврата.

Вызов из BADI

В СБИС САПЕР имеются реализации стандартных BADI и точек расширения для программ печати:

  • класс /SBIS/CL_J_3R_INV_BADI — для печати накладных,
  • класс /SBIS/CL_J3R_TORG12_BADI — для печати фактур,
  • точка расширения /SBIS/ENHI_J_3RV_TORG12_BIL — для печати актов.

Проверьте, что BADI: J_3R_TORG12_BADI, J_3R_INV_BADI и точка расширения ESJ_3RV_FORM_UPDATE активированы. Используейте готовые решения, реализованные в данных классах.

Если BADI активированы, установлен статус «Внедрение вызывается».

Пример вызова из BADI для программы печати накладной ТОРГ-12. В зависимости от флага gv_not_print мы либо печатаем, либо выходим из BADI и из программы печати.

METHOD j_3r_torg12_badi_interface~doc_details.
 
** I_VBDKL    TYPE VBDKL
** T_VBDPL    TYPE EHS_VBDPL_T
** EDITABLE   TYPE XFELD
** HDOC       TYPE J_3RV_HT12
** ITEMS      TYPE J_3RV_TT12
 
**************************************************************
*                 TENSOR SBIS EDO                            *
**************************************************************
    DATA lv_prog_and_field TYPE char255.
    TRY.
*" GET NAST
        "имя программы берем из инишки сверху
        FIELD-SYMBOLS: <lfs_prog_name> TYPE char40.
        ASSIGN ('(/SBIS/SAPLGF_PRINT_PROG)GV_PROG_NAME') TO <lfs_prog_name>.
        IF <lfs_prog_name> IS ASSIGNED.
 
          lv_prog_and_field = `(` && <lfs_prog_name> && `)` && 'NAST'.
          FIELD-SYMBOLS: <lfs_nast> TYPE nast.
*          ASSIGN ('(J_3RV_DELIV_PDF)NAST') TO <lfs_nast>.
          ASSIGN (lv_prog_and_field) TO <lfs_nast>.
          IF <lfs_nast> IS ASSIGNED.
*" MAPPING
            DATA cx_root TYPE REF TO cx_root.
            DATA cl_mapping TYPE REF TO /sbis/cl_mapping.
            CREATE OBJECT cl_mapping.
            CALL METHOD cl_mapping->calc_doc
              EXPORTING
                is_nast      = <lfs_nast>
              IMPORTING
                ev_not_print = gv_not_print.
          ELSE.
            "нет такой переменной - исключение!
            RAISE EXCEPTION TYPE /sbis/cx_core
              EXPORTING
                textid              = /sbis/cx_core=>/sbis/cx_core
                lv_error_msg_ext    = `Variable not assigned: '`
                                      && lv_prog_and_field && `'`
                lv_error_msg_detail = ''.
          ENDIF. " IF <lfs_nast> IS ASSIGNED.
 
*" EXIT FROM PRINT PROGRAM
          IF NOT gv_not_print IS INITIAL.
            lv_prog_and_field = `(` && <lfs_prog_name> && `)` && 'VBDKL'.
            FIELD-SYMBOLS: <lfs_vbdkl> TYPE vbdkl.
            "ASSIGN ('(J_3RV_DELIV_PDF)VBDKL') TO <lfs_vbdkl>.
            ASSIGN (lv_prog_and_field) TO <lfs_vbdkl>.
            IF <lfs_vbdkl> IS ASSIGNED.
              CLEAR <lfs_vbdkl>-vbeln. " хитрый способ выйти из прогр J_3RV_DELIV_PDF
            ELSE.
              "если в логике программы что-то поменялось - исключение!
              RAISE EXCEPTION TYPE /sbis/cx_core
                EXPORTING
                  textid              = /sbis/cx_core=>/sbis/cx_core
                  lv_error_msg_ext    = `Variable not assigned: '`
                                        && lv_prog_and_field && `'`
                  lv_error_msg_detail = ''.
            ENDIF. " IF <lfs_vbdkl> IS ASSIGNED.
          ENDIF.
        ENDIF. " IF <lfs_prog_name> IS ASSIGNED.
 
      CATCH /sbis/cx_core INTO cx_core.
        DATA  lv_cur_prog  TYPE char255.
        DATA  lv_cur_form  TYPE char255.
        CALL METHOD /sbis/cl_core=>get_current_progname
          IMPORTING
            ev_prog_name = lv_cur_prog
            ev_form_name = lv_cur_form.
        " exception проходит через прогр печати без текста!
        FIELD-SYMBOLS: <fs_exc> TYPE /sbis/s_cx_core.
        ASSIGN ('(/SBIS/SAPLGF_PRINT_PROG)GS_EXC') TO <fs_exc>.
        IF  <fs_exc>    IS ASSIGNED.
          <fs_exc>-error_msg_ext    = cx_core->lv_error_msg_ext.
          <fs_exc>-error_msg_detail = cx_core->lv_error_msg_detail
                                    && ` <= ` && lv_cur_prog && `->` && lv_cur_form.
        ENDIF.
        RAISE EXCEPTION TYPE /sbis/cx_core
          EXPORTING
            textid              = cx_core->textid
            lv_error_msg_ext    = cx_core->lv_error_msg_ext
            lv_error_msg_detail = cx_core->lv_error_msg_detail
                                    && ` <= ` && lv_cur_prog && `->` && lv_cur_form.
    ENDTRY.
  ENDMETHOD.

Вызов из формуляра SMARTFORM

Необходим, когда в системе нет отдельной программы печати (например, в отраслевых решениях), или когда значительная часть логики перенесена в формуляр.

Особенности вызова из формуляров

  • Из программы печати вызывается формуляр. Из него необходимо вызвать код СБИС и выйти из формуляра, а потом выйти из программы. 

  • Данные формуляра, которые передаются в САПЕР, должны быть объявлены глобально.
  • Вставить вызов кода СБИС необходимо в элемент смартформы «строки программы», где есть доступ к подготовленным данным печати. Например, в основной цикл по позициям. В инициализацию вставлять не имеет смысла — там у СБИС САПЕР нет доступа через assign к глобальным переменным формуляра, а также не обеспечивается корректный выход из формуляра/ФМ с rc=0.

Пример кода СБИС:

* TENSOR SBIS EDO
TRY.
    DATA cx_root TYPE REF TO cx_root.
    DATA lv_not_print TYPE c VALUE ''.
    DATA cl_mapping TYPE REF TO /sbis/cl_mapping.
    CREATE OBJECT cl_mapping.
    CALL METHOD cl_mapping->calc_doc_efg
      EXPORTING
        iv_ini_name  = 'ZSF_INVOICE'
      IMPORTING
        ev_not_print = lv_not_print.
    IF lv_not_print = 'X'.
      " надо выйти без печати!
      " Set error message
      CALL FUNCTION 'SSFRT_WRITE_ERROR'
        EXPORTING
          i_msgid = '00'
          i_msgno = '208'
          i_msgv1 = 'SBIS: not print'.
* Raise the excption
      user_exception user_canceled.
    ENDIF.
 
  CATCH /sbis/cx_core INTO cx_core.
    " надо выйти без печати!
    " SET error message
    CALL FUNCTION 'SSFRT_WRITE_ERROR'
      EXPORTING
*       I_ERRNUMBER =
        i_msgid = '00'
*       I_MSGTY = 'E'
        i_msgno = '208'
        i_msgv1 = 'SBIS: not print'.
* Raise the excption
    user_exception user_canceled.
 
  CATCH cx_root INTO cx_root.
    " надо выйти без печати!
    " SET error message
    CALL FUNCTION 'SSFRT_WRITE_ERROR'
      EXPORTING
*       I_ERRNUMBER =
        i_msgid = '00'
*       I_MSGTY = 'E'
        i_msgno = '208'
        i_msgv1 = 'SBIS: not print'.
* Raise the excption
    user_exception user_canceled.
ENDTRY.

Как правило, программа печати не требует изменений и сама формирует необходимый код возврата.

Вызов из формуляра PDF

Требуется в случаях, когда в системе нет отдельной программы печати (например, в отраслевых решениях), или когда значительная часть логики перенесена в формуляр.

Особенности вызова из формуляров

  • Из программы печати вызывается формуляр. Из него необходимо вызвать код СБИС и выйти из формуляра, а потом выйти из программы. 
  • Вставить вызов кода СБИС необходимо в интерфейсе формуляра в код инициализации или в подпрограмму, где есть доступ к подготовленным данным печати.

Пример кода СБИС:

**************************************************************
*                 TENSOR SBIS EDO                            *
**************************************************************
  TRY.
      DATA cx_root TYPE REF TO cx_root.
      DATA lv_not_print TYPE c VALUE ''.
      DATA cl_mapping TYPE REF TO /sbis/cl_mapping.
      CREATE OBJECT cl_mapping.
      CALL METHOD cl_mapping->calc_doc
        exporting
          iv_ini_name = 'DP_TOVTORGPR_1175010'  " 
        IMPORTING
          ev_not_print = lv_not_print.
      IF lv_not_print = 'X'.
        return.
        MESSAGE ID 'SU' TYPE '-' NUMBER 000 WITH 'SBIS_COMPLETE'
          RAISING usage_error.
      ENDIF.
    CATCH cx_root INTO cx_root.
  ENDTRY.

В программе печати необходимо предусмотреть корректный выход с правильным кодом возврата. Пример кода:

CALL FUNCTION func_module_name
        EXPORTING
          /1bcdwb/docparams  = fp_docparams
          h_item             = items
          h_header           = h_doc
        IMPORTING
          /1bcdwb/formoutput = ls_formoutput
        EXCEPTIONS
          usage_error        = 1
          system_error       = 2
          internal_error     = 3.
 
**************************************************************
*                 TENSOR SBIS EDO - BEGIN                    *
**************************************************************
      IF sy-subrc <> 0 AND sy-msgv1 = 'SBIS_COMPLETE'.
        sy-subrc = 0.
        CALL FUNCTION 'FPCOMP_FORM_END'
          EXCEPTIONS
            usage_error    = 1
            system_error   = 2
            internal_error = 3
            OTHERS         = 4.
      ELSEIF sy-subrc <> 0.
**************************************************************
*                 TENSOR SBIS EDO - END                      *
**************************************************************
        retcode = sy-subrc.
        PERFORM protocol_update.
        MESSAGE e073 INTO gv_dummy.
        PERFORM protocol_update.
      ENDIF.
0
0
Оставьте свой отзыв:
ОТПРАВИТЬ