Текущее время: Чт, мар 28 2024, 19:06

Часовой пояс: UTC + 3 часа


Правила форума


ВНИМАНИЕ!

Вопросы по SAP Query и Quick View - сюда



Начать новую тему Ответить на тему  [ Сообщений: 2 ] 
Автор Сообщение
 Заголовок сообщения: Как программно присвоить триггер (Action в PPF Post Processing Framework) к фактуре?
СообщениеДобавлено: Вс, сен 05 2021, 16:18 
Младший специалист
Младший специалист

Зарегистрирован:
Сб, апр 11 2020, 21:34
Сообщения: 53
Пытаюсь сделать программу для массового присвоения триггеров (Action PPF Post Processing Framework) к фактурам.
Исходные данные:
В транзакции BEA_ACTION_DEF создан профиль (Action Profile) Z_IPMI_BILLING с триггером (Аction) Z_IPMI_BILLDOC, который надо присвоить выборке фактур.
В транзакции /BEA/IPMI11 можно присвоить триггер (Action) к выбранной из таблицы /1BEA/IPMI_BDH фактуре. Mне нужно сделать автоматическое присвоение триггера для выборки фактур, чтобы потом все выбранные фактуры с присвоенным триггером обработать в программе RSPPFPROCESS.
Ориентируюсь на два следующих руководства:
http://pavelgk.pbworks.com/f/Post+Processing+Framework+(PPF)+Guidelines+for+application+developers.pdf
http://www.sapspot.com/sap-transportation-management-trigger-ppf-post-processing-framework-action-from-stand-alone-code/
Также пытаюсь следовать логике присвоения триггера фактуре в транзакции /BEA/IPMI11 с помощью отладчика.

Выкладываю эскиз кода. На данный момент не удается присвоить триггер фактуре. Просьба профессионалов скорректировать и направить на путь истиный.

0) Используемые переменные:
Code:
data: bdh_guid      type bea_bdh_guid.
data: g_manager type ref to cl_manager_ppf.
data:lo_trigger    type ref to cl_trigger_ppf.
data: lo_appl_object  type ref to cl_bea_ppf.
data:lo_trigger    type ref to cl_trigger_ppf.
data: lv_applkey      type ppfdappkey.
data: lo_partner      type ref to cl_bea_partner_ppf,
      lo_partner_coll type ref to cl_partner_coll_ppf.
data: l_notif_found type dnot_flag.
data: lt_context     type ppftcntxts.
data:  ls_context      type ppfdctxtir.

1) Получаем instance of PPF manager:
Code:
try.
      g_manager = cl_manager_ppf=>get_instance( ).
      check g_manager is bound.
  endtry.


2) Список фактур передается во внутреннюю таблицу. На данном этапе список ограничен фактурой с id='4000100573':
Code:
select bdi~bdi_guid,  bdh~bdh_guid,  bdi~src_guid, bdh~headno_ext, bdi~src_headno,bdh~bill_date,bdh~bill_type,bdi~item_category,bdh~bill_org, bdh~parset_guid
   into table @lt_lty_bdi
   from  /1bea/ipmi_bdi as bdi

   inner join /1bea/ipmi_bdh as bdh on bdi~bdh_guid = bdh~bdh_guid
   "where bill_type  between 'ZIF1' and 'ZIF8' and  bdi~src_headno in @s_objid and bdh~headno_ext in @s_faktid "and bdh~bill_org  > 0.
   where bdh~headno_ext = '4000100573'.

loop at lt_lty_bdi into ls_lty_bdi.   "цикл через список фактур


3) Создаем persistence object lo_appl_object для выбранной фактуры:
Code:
    try.
        lo_appl_object =
          ca_bea_ppf=>agent->get_persistent( ls_lty_bdi-bdh_guid ).
      catch cx_os_object_not_found.
        lo_appl_object =
          ca_bea_ppf=>agent->create_persistent( ls_lty_bdi-bdh_guid ).
        lo_appl_object->set_bea_name('IPMI').   "is_bty-application
    endtry.


4) Создаем и заполняем объект контекста к lo_appl_object:
Code:
if l_context is initial.
      create object l_context.
    endif.

    call function 'BEA_PPF_O_GET_APPLKEY'    "Трансформация номера фактуры в корректный lv_applkey: IPMI_4000100573
      exporting
        iv_application = 'IPMI'         "  is_bty-application
        iv_headno_ext  = ls_lty_bdi-headno_ext
      importing
        ev_applkey     = lv_applkey.

    l_context->name =     'Z_IPMI_BILLING'.       " Action Profile
    l_context->appl = lo_appl_object.             "Здесь передается параметр созданного persistence object  lo_appl_object для выбранной фактуры
    l_context->applctn =  'BILLING'.              " Application Name.   
ls_context = l_context.
    append ls_context to lt_context.



5) Выборка по business partner и добавление выборки в объект контекста:
Code:
call function 'BEA_PAR_O_GET'
      exporting
        iv_parset_guid = ls_lty_bdi-parset_guid
      importing
        et_par         = lt_partner
      exceptions
        reject         = 1
        others         = 2.
    loop at lt_partner into ls_partner.
*     create a partner object
      create object lo_partner
        exporting
          ip_partner_role  = ls_partner-partner_fct
          ip_partner_no    = ls_partner-partner_no
          ip_partner_text  = ''
          ip_zav_addressno = ls_partner-addr_nr
          ip_zav_persno    = ls_partner-addr_np
          ip_zav_addr_type = ls_partner-addr_type.
*    add partner object to partner collection
      call method lo_partner_coll->add_element( lo_partner ).
    endloop.
* update partner collection to context
    loop at lt_context assigning <lf_context>.
      <lf_context>->partner = lo_partner_coll.
    endloop.


6) Создаем объект триггера (Action = Z_IPMI_BILLDOC ) на основе ранее созданного объекта контекста и instance of ppf manager
На данном этапе происходит сбой. Триггер не инизиализируется:
Code:
   if lo_trigger is initial.
      " Create trigger for PPF action
      g_manager->create_trigger(
      exporting
      ip_ttype_name = 'Z_IPMI_BILLDOC'   "iv_ttype
      io_context = l_context
      receiving
      ro_trigger = lo_trigger
      exceptions
      empty_triggertype = 1
      empty_context = 2
      others = 3 ).
      if sy-subrc <> 0.
        raise error_trigger_creation.
      endif.
    endif.

    g_manager->set_applkey(   "* Set application key for all triggers of the context
    exporting
    ip_applkey = lv_applkey
    io_context = l_context ).

commit work and wait.

  endloop.

Возможно, надо вызывать метод g_manager->add_trigger(...)
Но как тогда добавить необходимый триггер Z_IPMI_BILLDOC? В данном методе нет такого параметра.
Если кто-нибудь имеет опыт в данном вопросе, большая просьба скорректировать, подсказать.


Пометить тему как нерешенную
Вернуться к началу
 Профиль Отправить email  
 
 Заголовок сообщения: Re: Как программно присвоить триггер (Action в PPF Post Processing Framework) к фактуре?  Тема решена
СообщениеДобавлено: Вт, ноя 22 2022, 19:18 
Младший специалист
Младший специалист

Зарегистрирован:
Сб, апр 11 2020, 21:34
Сообщения: 53
Сохраню здесь. Решение с год как работает.
Обобщение: массовое присвоение Actions в CRM к фактурам с последующей oбработкой в программе RSPPFPROCESS.

*
Code:
&---------------------------------------------------------------------*
*& Report ZREP_FAKTIRA_ARCHIV
*&---------------------------------------------------------------------*
*& REPORT für die Massenzuweisung von Aktionen zur Fakturen.
*&
*&  Aktionsprofil: Z_IPMI_BILLING
*&  Aktion Z_IPMI_BILLDOC: wenn die BILL_ORG der Faktura der GP # 4 ist und das BILL_DATE der Faktura < '20210407' und die Nummer des Vertrags zur Faktura zwischen '0900000000' und '0910000000' liegt
*&  Aktion Z_IPMI_BILLDOC_KOMMI: wenn die BILL_ORG der Faktura der GP # 6007 ist und das BILL_DATE der Faktura < '20210407' und die Nummer des Vertrags zur Faktura zwischen '0910000000' und '0920000000' liegt
*&  Aktion Z_IPMI_BILLDOC_VERSCHM: wenn die BILL_ORG der Faktura der GP # 4 oder der GP # 6007 ist und das BILL_DATE der Faktura > '20210407' sowie die Nummer des Vertrags zur Faktura größer oder gleich '0920000000' ist
*&---------------------------------------------------------------------*
report zrep_faktura_archiv.

tables :/1bea/ipmi_bdh,/1bea/ipmi_bdi.

types:
  begin of lty_bdi,
    "    bdi_guid      type bea_bdi_guid,
    bdh_guid    type bea_bdh_guid,
    src_guid    type crmt_object_guid,
    headno_ext  type bea_headno_ext,
    src_headno  type bea_src_headno,
    bill_date   type bea_bill_date,
    bill_type   type bea_bill_type,
    "    item_category type bea_item_category,
    bill_org    type bea_bill_org,
    parset_guid type bea_parset_guid,
  end of lty_bdi.

constants:
      lc_act1       type string value 'IPMI_BILLDOC'.

data: lv_ppf_mode     type ppfdmode,
      gv_ttype_name   type  ppfdtt,
      lo_ppf_manager  type ref to cl_manager_ppf,
      gv_data_changed type bea_boolean,
      lv_act          type ppfdtt,
      gv_headno_alt   type  bea_headno_ext,
      lt_trigger      type ppfttrgor,
      lt_partner      type beat_par_wrk,
      ls_partner      type beas_par_wrk,
      lt_lty_bdi      type table of lty_bdi,
      ls_lty_bdi      like line of lt_lty_bdi,
      lv_erfolg       type i.

data: gt_inactiv_trigger type ppfttrgor.
data: gt_activ_trigger type ppfttrgor.
data: gs_activ_trigger type ppfdtrgor.
data: gs_inactiv_trigger type ppfdtrgor.
data ls_action type crmt_action_get.
data lt_action type crmt_action_get_tab.


select-options:
s_faktid for /1bea/ipmi_bdh-headno_ext,
s_objid for /1bea/ipmi_bdi-src_headno.

data: l_context type ref to cl_notif_context_ppf.
data: l_ez_context type ref to ppfdcntxt.
"data:  l_appl_object type ref to cl_notif_ppf.
data: g_manager type ref to cl_manager_ppf.
"data: l_notif_found type dnot_flag.
data: lt_context     type ppftcntxts.
data: ls_context      type ppfdctxtir.
data: gd_trigger         type ref to data.
"data: go_proxy       type ref to cl_okcode_ppf.
data:lo_trigger    type ref to cl_trigger_ppf.
data: lr_print_medium_ppf   type ref to  cl_sf_print_ppf.
data: lv_applkey      type ppfdappkey.
data: lo_appl_object  type ref to cl_bea_ppf.
data: lo_partner      type ref to cl_bea_partner_ppf,
      lo_partner_coll type ref to cl_partner_coll_ppf.
data: lv_status type ppfdtstat.
data: o_coll type ref to cl_trigger_coll_ppf.
"data: lref_bcs           type ref to cl_bcs.

field-symbols <lf_context> type ppfdctxtir.

initialization.

  "  s_objid[]  = value #( ( sign = 'I' option = 'BT' low = '0800000000' high = '0809999999' )
  "                        ( sign = 'I' option = 'BT' low =  '0900000000' high = '0920000000' )
  "                      ).

start-of-selection.

  data: lv_answer type c.

  lv_act = lc_act1.

  try.
      g_manager = cl_manager_ppf=>get_instance( ).
      check g_manager is bound.
  endtry.


  g_manager->locale_update = 'X'.

  data: it_result type table of zrep_forecast_line,
        lv_excl   type char4.

  select distinct
"    bdi~bdi_guid,
    bdh~bdh_guid,
    bdi~src_guid,
    bdh~headno_ext,
    bdi~src_headno,
    bdh~bill_date,
    bdh~bill_type,
"    bdi~item_category,
    bdh~bill_org,
    bdh~parset_guid
    into table @lt_lty_bdi
    from  /1bea/ipmi_bdi as bdi
    inner join /1bea/ipmi_bdh as bdh on bdi~bdh_guid = bdh~bdh_guid
    where
    bdi~item_category <> 'ZI11' and bdi~item_category <> 'ZI22' and
       "( ( bill_type  between 'ZIF1' and 'ZIF8' )  and ( src_headno between  '0800000000'  and '0899999999' ) and  bdi~src_headno in @s_objid and bdh~headno_ext in @s_faktid "and bdh~bill_org  > 0.
        bdi~src_headno in @s_objid and bdh~headno_ext in @s_faktid.

  sort   lt_lty_bdi by src_headno headno_ext.


  call function 'POPUP_TO_CONFIRM'
    exporting
      titlebar              = 'Aktionen zu den ausgewählten Fakturen zuweisen'
      text_question         = 'Wollen Sie wirklich die Aktionen zu den ausgewählten Fakturen zuweisen?'
      text_button_1         = 'Ja'
      display_cancel_button = ''
      icon_button_1         = 'ICON_OKAY'
      text_button_2         = 'Nein'
      icon_button_2         = 'ICON_CANCEL'
      default_button        = '2'
    importing
      answer                = lv_answer "Rückgabewerte: '1', '2', 'A'
    exceptions
      text_not_found        = 1
      others                = 2.

  if sy-subrc <> 0.
    message i531(0u) with 'Fehler beim Funktionsbaustein POPUP_TO_CONFIRM'.
    return.
  endif.

  if lv_answer = '2' or
     lv_answer = 'A'.
    return.
  endif.

  clear gv_headno_alt.

  loop at lt_lty_bdi into ls_lty_bdi.
    lv_erfolg = 0.

    if gv_headno_alt <> ls_lty_bdi-headno_ext.

      gv_headno_alt = ls_lty_bdi-headno_ext.

      clear: lo_appl_object.
      refresh lt_context.
      try.
          lo_appl_object =
            ca_bea_ppf=>agent->get_persistent( ls_lty_bdi-bdh_guid ).
        catch cx_os_object_not_found.
          lo_appl_object =
            ca_bea_ppf=>agent->create_persistent( ls_lty_bdi-bdh_guid ).
          lo_appl_object->set_bea_name('IPMI').   "is_bty-application
      endtry.

      clear l_context.
      clear lo_trigger.
      if l_context is initial.
        create object l_context.
      endif.

      "CREATE OBJECT lref_bcs.

      call function 'BEA_PPF_O_GET_APPLKEY'
        exporting
          iv_application = 'IPMI'         "  is_bty-application
          iv_headno_ext  = ls_lty_bdi-headno_ext
        importing
          ev_applkey     = lv_applkey.


      if ( ls_lty_bdi-src_headno < '0900000000' ).
        l_context->name =     'IPMI_BILLING'.
      else.
        l_context->name =     'Z_IPMI_BILLING'.       "l_type_notif-ppf_profil.
      endif.

      l_context->appl = lo_appl_object.
      l_context->applctn =  'BILLING'.              "l_type_notif-ppf_appl.


      o_coll = g_manager->get_triggers( l_context ).
      o_coll->reset_iterator( ).

      do.
        call method o_coll->get_next_element
          receiving
            ro_element = lo_trigger
          exceptions
            others     = 1.
        if sy-subrc ne 0.
          exit.
        endif.

        if lo_trigger is not initial.
          lv_status  = lo_trigger->get_status( ).
          if lv_status = 0.
            g_manager->delete_trigger( io_context = l_context io_trigger = lo_trigger io_force = crmkc_con_yes ).
          endif.
        endif.
      enddo.

      "      ls_context = l_context.
      "     append ls_context to lt_context.

      "      check lt_context is not initial.
*
**   create partner collection
*      create object lo_partner_coll.
*
*      call function 'BEA_PAR_O_GET'
*        exporting
*          iv_parset_guid = ls_lty_bdi-parset_guid
*        importing
*          et_par         = lt_partner
*        exceptions
*          reject         = 1
*          others         = 2.
*      loop at lt_partner into ls_partner.
**     create a partner object
*        create object lo_partner
*          exporting
*            ip_partner_role  = ls_partner-partner_fct
*            ip_partner_no    = ls_partner-partner_no
*            ip_partner_text  = ''
*            ip_zav_addressno = ls_partner-addr_nr
*            ip_zav_persno    = ls_partner-addr_np
*            ip_zav_addr_type = ls_partner-addr_type.
**    add partner object to partner collection
*        call method lo_partner_coll->add_element( lo_partner ).
*      endloop.
** update partner collection to context
*      loop at lt_context assigning <lf_context>.
*        <lf_context>->partner = lo_partner_coll.
*      endloop.
*
*      clear gv_ttype_name.
*      clear lo_trigger.
*
*      call method g_manager->get_active_triggers
*        exporting
*          it_contexts = lt_context
*        importing
*          et_triggers = gt_activ_trigger.
*
*      loop at gt_inactiv_trigger into gs_inactiv_trigger.
*        ls_action-guid = gs_inactiv_trigger->read_guid( ).
*        "                ls_action-def = gs_inactiv_trigger->get_ttype( ).
*        "                ls_action-text = cl_view_service_ppf=>get_descrp_for_dropdown( io_trigger = gs_inactiv_trigger ).
*        "lv_status  =  gs_inactiv_trigger->get_status( ).
*      endloop.
*
*      if  lines( gt_activ_trigger ) > 0.
*        g_manager->delete_all_triggers_for_object( lo_appl_object ).
*      endif.
*
*

*
      format color col_normal.

      if (  ls_lty_bdi-src_headno between '0800000000' and '0899999999') .

          gv_ttype_name = 'IPMI_BILLDOC'.

        perform create_trigger using gv_ttype_name
                                     l_context
                               changing lv_erfolg.

        if lv_erfolg = 0.
          write: / ls_lty_bdi-src_headno,| |, ls_lty_bdi-headno_ext,|   |,ls_lty_bdi-bill_type, |      |, ls_lty_bdi-bill_date, |       |,ls_lty_bdi-bill_org,  |    |, gv_ttype_name, |  |, 'ERFOLG!'.  "ls_lty_bdi-bdh_guid,  ls_lty_bdi-src_guid,
        endif.

      elseif ( ( ls_lty_bdi-src_headno between '0900000000' and '0900099999') and ls_lty_bdi-bill_org =  '0000000004' ).  "and ls_lty_bdi-bill_date <  '20210407'


          gv_ttype_name = 'Z_IPMI_BILLDOC'.
*
        perform create_trigger using gv_ttype_name
                                     l_context
                               changing lv_erfolg.

        if lv_erfolg = 0.
          write: / ls_lty_bdi-src_headno,| |, ls_lty_bdi-headno_ext,|   |,ls_lty_bdi-bill_type, |      |, ls_lty_bdi-bill_date, |       |,ls_lty_bdi-bill_org,  |    |, gv_ttype_name, |  |, 'ERFOLG!'.  "ls_lty_bdi-bdh_guid,  ls_lty_bdi-src_guid,
        endif.

      elseif ls_lty_bdi-src_headno between '0910000000' and '0910099999' and ( ls_lty_bdi-bill_org = '0000006007' or ls_lty_bdi-bill_org = '0000000004' ). "and ls_lty_bdi-bill_date <  '20210407'.

          gv_ttype_name = 'Z_IPMI_BILLDOC_KOMMI'.
*
        perform create_trigger using gv_ttype_name
                                     l_context
                               changing lv_erfolg.
        if lv_erfolg = 0.
          write: / ls_lty_bdi-src_headno,| |, ls_lty_bdi-headno_ext,|   |,ls_lty_bdi-bill_type, |      |, ls_lty_bdi-bill_date, |       |,ls_lty_bdi-bill_org,  |    |, gv_ttype_name, |  |, 'ERFOLG!'.  "ls_lty_bdi-bdh_guid,  ls_lty_bdi-src_guid,
        endif.

"     elseif ( ls_lty_bdi-src_headno between '0920000000' and  '0929999999' ).
        elseif ( ls_lty_bdi-src_headno >= '0920000000').
      "  and ( ls_lty_bdi-bill_org = '0000006007' or  ls_lty_bdi-bill_org = '0000000004' ) and ls_lty_bdi-bill_date >  '20210407'.
        gv_ttype_name = 'Z_IPMI_BILLDOC_VERSCHM'.

        perform create_trigger using gv_ttype_name
                                     l_context
                               changing lv_erfolg.

        if lv_erfolg = 0.
          write: / ls_lty_bdi-src_headno,| |, ls_lty_bdi-headno_ext,|   |,ls_lty_bdi-bill_type, |      |, ls_lty_bdi-bill_date, |       |,ls_lty_bdi-bill_org,  |    |, gv_ttype_name, |  |, 'ERFOLG!'.  "ls_lty_bdi-bdh_guid,  ls_lty_bdi-src_guid,
        endif.

*       else.
*
*          gv_ttype_name = 'Z_IPMI_BILLDOC'.
*          perform create_trigger using gv_ttype_name
*                                     l_context
*                               changing lv_erfolg.
*          if lv_erfolg = 0.
*          write: / ls_lty_bdi-src_headno,| |, ls_lty_bdi-headno_ext,|   |,ls_lty_bdi-bill_type, |      |, ls_lty_bdi-bill_date, |       |,ls_lty_bdi-bill_org,  |    |, gv_ttype_name, |  |, 'ERFOLG!'.  "ls_lty_bdi-bdh_guid,  ls_lty_bdi-src_guid,
*        endif.

      endif.

    endif.

  endloop.

end-of-selection.

  commit work and wait.

form create_trigger using lv_ttype_name type  ppfdtt
                          lo_context type ref to cl_notif_context_ppf
                    changing lv_erfolg type integer.



  data: ev_rc type i.
  data: lref_bcs           type ref to cl_bcs.
  data: lo_medium  type ref to if_medium_ppf.
  data: lo_trigger  type ref to cl_trigger_ppf.

  clear lo_trigger.


  g_manager->create_trigger(
     exporting
     ip_ttype_name =    lv_ttype_name  "iv_ttype
     io_context = lo_context
     receiving
     ro_trigger =  lo_trigger "co_trigger
     exceptions
     empty_triggertype = 1
     empty_context = 2
     others = 3 ).
  if  sy-subrc <> 0.
    format color col_negative.
    lv_erfolg = 1.
    write: / ls_lty_bdi-src_headno,| |, ls_lty_bdi-headno_ext,|   |,ls_lty_bdi-bill_type, |      |, ls_lty_bdi-bill_date, |       |,ls_lty_bdi-bill_org,  |    |, gv_ttype_name,  |  |, 'FEHLER!'. "ls_lty_bdi-bdh_guid,  ls_lty_bdi-src_guid,
    "  raise error_trigger_creation.
    clear lo_trigger.
  endif.


  if lo_trigger is not initial.
    lo_trigger->set_partindep( i_partindep = abap_true ).
  endif.

  if lr_print_medium_ppf is initial.
    create object lr_print_medium_ppf.
  endif.

  if  lo_trigger is bound.
*    create object lref_bcs.
    lo_medium = lo_trigger->get_medium( ).
    if lo_medium is bound.
      lr_print_medium_ppf ?= lo_medium.
      call method lr_print_medium_ppf->set_device( 'LOCL' ).
      call method lr_print_medium_ppf->set_copies( '001' ).


***Set the medium of PPF Action
      call method lo_trigger->set_medium
        exporting
          i_medium = lr_print_medium_ppf.
    endif.
  endif.

  g_manager->set_applkey(
  exporting
     ip_applkey = lv_applkey
     io_context = l_context ).


*  call method co_trigger->execute
*    receiving
*      rp_rc                   = ev_rc
*    exceptions
*      empty_medium_reference  = 1
*      empty_appl_reference    = 2
*      locked                  = 3
*      document_is_locked      = 4
*      inactive                = 5
*      startcondition_not_true = 6
*      others                  = 7.

  clear gt_inactiv_trigger.

  call method g_manager->get_inactive_triggers
    exporting
      it_contexts = lt_context
    importing
      et_triggers = gt_inactiv_trigger.

  if lines( gt_inactiv_trigger ) > 0.
    "   write: /   ls_lty_bdi-headno_ext.
    loop at  gt_inactiv_trigger into gs_inactiv_trigger.
      gs_inactiv_trigger->if_action_ppf~activate( exceptions failed = 1 ).
    endloop.
  endif.


endform.


Пометить тему как нерешенную
Вернуться к началу
 Профиль Отправить email  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 2 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB