关于接受Release管理的PR已经创建了PO后还能Unrelease的原因浅析
作者:袁云飞(AlbertYuan)- 微信号yuanalbert
以下内容均为原创,希望对初学者有一些辅助作用,本人主要从事MM/QM/WM的相关工作,不专业处请多多指点,十足干货,码字不易,且行且珍惜,加入粉丝您将能看到更多相关主题文章,你们的关注就是我努力的动力,转载请引用出处,感激不尽;
关于这个问题是比较有争议的,很多小伙伴们应该碰到过,那就是当你执行完PR的审批之后,参考该PR完成了PO的创建,按理说,PR的数据已经拷贝到了PO,PR往往作为证据凭证进行保留,有些公司还要求下达完成的PR是不能修改的,都是为了保证PR审批数据的完整性和不可变性;
但我们发现,PR已经被转化为PO后,PR本身是可以取消审批的,由于很多公司将PR设计为PR审批完成后不可修改,导致取消审批后的PR,就变为可以再次修改,这样往往出现一种情况,就是修改后的PR和原PO的某些数据不一致了,让人非常的头疼;而中国的部分企业往往对审批是一种走马观花的态度,这种问题就显得更加凸显;
我们看看下面的截图;
可以看到,该PR完成审批后已经存在参考其的PO了,但ME54N里依然是可以取消该PR的审批的;而由于PR和PO的数据连接仅仅在EBAN/EKPO里通过相互的号码进行关联,所以取消审批的PR所产生的数据修改,其实是无法进行校验的,不一致由此产生;
其实这个“功能”设计是SAP认可的,至于原因,是在无法理解,至少国内很多企业是不太认可这种行为的,咨询过很多行业顾问,他们都比较认同这种看法,或者至少做出一个switch开关进行灵活的处理;
进过代码分析发现SAP已经将代码修改为PR创建PO后依然可以取消审批这个逻辑了;如果小伙伴们需要PO创建后,不能进行取消审批动作;可以创建一个消息 ME 110(ME 109);然后进行相关的修正代码即可,有专用的NOTE完成此事(SAP确实比较糊涂);
需要修正的地方一个在类里,一个在一个程序段里;
*$*$----------------------------------------------------------------$*$*
*$ Correction Inst. 0120031469 0000285017 $*
*$ Req. Corr. Instructions 0120031469 0000458090 Note 0000934357 $*
*$ 0120031469 0000458796 Note 0000934357 $*
*$ 0120031469 0000490159 Note 0000898822 $*
*$ 0120031469 0000490160 Note 0000898822 $*
*$ 0120031469 0000490161 Note 0000898822 $*
*$ 0120061532 0000804001 Note 0000954337 $*
*$ 0120061532 0000804002 Note 0000954337 $*
*$ 0120061532 0000804003 Note 0000954337 $*
*$--------------------------------------------------------------------$*
*$ Valid for : $*
*$ Software Component SAP_APPL SAP Application $*
*$ Release 470 To SAPKH47018 $*
*$ Release 500 Fm SAPKH50001 $*
*$ Release 600 Fm SAPKH60001 $*
*$ Release 602 All Support Package Levels $*
*$ Release 603 All Support Package Levels $*
*$ Release 604 Fm SAPKH60401 $*
*$ Release 605 All Support Package Levels $*
*$ Release 606 Fm SAPKH60601 $*
*$ Release 616 All Support Package Levels $*
*$ Release 617 Fm SAPKH61701 $*
*$ Release 618 All Support Package Levels $*
*$--------------------------------------------------------------------$*
*$ Changes/Objects Not Contained in Standard SAP System $*
*$*$----------------------------------------------------------------$*$*
*&--------------------------------------------------------------------*
*& Object METH CL_RELEASE_STATE_MM
*& IF_RELEASE_STATE_MM~RESET_RELEASE
*& Object Header CLAS CL_RELEASE_STATE_MM
*&--------------------------------------------------------------------*
...
METHOD if_release_state_mm~reset_release.
DATA: l_frgot TYPE frgot,
l_t161s TYPE t161s,
l_frgzu LIKE my_frgzu,
l_indicator LIKE my_indicator,
*>>>> START OF DELETION <<<<<
l_is_released LIKE is_released.
*>>>> END OF DELETION <<<<<<<
*>>>> START OF INSERTION <<<<
l_is_released LIKE is_released,
l_frgzu_c LIKE my_frgzu, "686022
l_indicator_c LIKE my_indicator, "686022
l_is_released_c LIKE is_released. "686022
*>>>> END OF INSERTION <<<<<<
...
MOVE: my_frgzu TO l_frgzu,
my_indicator TO l_indicator,
is_released TO l_is_released.
*>>>> START OF DELETION <<<<<
CALL METHOD my_strategy->propagate_state
*>>>> END OF DELETION <<<<<<<
*>>>> START OF INSERTION <<<<
MOVE: my_frgzu TO l_frgzu_c, "686022
my_indicator TO l_indicator_c, "686022
is_released TO l_is_released_c. "686022
CALL METHOD my_strategy->propagate_state
*>>>> END OF INSERTION <<<<<<
...
SELECT SINGLE * FROM t161s INTO l_t161s WHERE
frgkz = l_indicator.
CASE im_statu.
*- Banf bereits angefragt - neues Freigabekz. muss Anfrage erlauben ---*
WHEN 'A'.
IF l_t161s-frang EQ space.
*>>>> START OF DELETION <<<<<
RAISE rfq_exists.
ENDIF.
*- Banf bereits bestellt - neues Freigabekz. muss Bestellung erlauben -*
WHEN 'B'.
IF l_t161s-frbst EQ space.
*>>>> END OF DELETION <<<<<<<
*>>>> START OF INSERTION <<<<
PERFORM enaco_2 IN PROGRAM sapfmmex USING 'ME' '109'."686022
CASE sy-subrc. "686022
WHEN 02. "686022
my_frgzu = l_frgzu_c. "686022
my_indicator = l_indicator_c. "686022
is_released = l_is_released_c. "686022
ENDCASE. "686022
RAISE rfq_exists.
ENDIF.
*- Banf bereits bestellt - neues Freigabekz. muss Bestellung erlauben -*
WHEN 'B'.
IF l_t161s-frbst EQ space.
PERFORM enaco_2 IN PROGRAM sapfmmex USING 'ME' '110'."686022
CASE sy-subrc. "686022
WHEN 02. "686022
my_frgzu = l_frgzu_c. "686022
my_indicator = l_indicator_c. "686022
is_released = l_is_released_c. "686022
ENDCASE. "686022
*>>>> END OF INSERTION <<<<<<
...
*&--------------------------------------------------------------------*
*&--------------------------------------------------------------------*
*& Object REPS LMEREQFDE
*& Object Header FUGR MEREQ
*&--------------------------------------------------------------------*
...
ENDMETHOD.
"if_dcm_adapter~IS_uncomplete_VERSION_ALLOWED
METHOD if_dcm_adapter~is_deletion_allowed.
*...dummy implementation, not used for reqs to avoid warning
re_bool = mmpur_no.
*>>>> START OF DELETION <<<<<
ENDMETHOD.
*>>>> END OF DELETION <<<<<<<
*>>>> START OF INSERTION <<<<
ENDMETHOD. "if_dcm_adapter~is_deletion_allowed
*>>>> END OF INSERTION <<<<<<
...
WHEN 1. MESSAGE e241(me) WITH im_code RAISING failed.
WHEN 2. MESSAGE e105(me) RAISING failed.
WHEN 3. MESSAGE e104(me) RAISING failed.
WHEN 5. MESSAGE e108(me) RAISING failed.
WHEN 6. " MESSAGE e109(me) raising failed.
*>>>> START OF DELETION <<<<<
WHEN 7. " MESSAGE e110(me) raising failed.
*>>>> END OF DELETION <<<<<<<
*>>>> START OF INSERTION <<<<
PERFORM enaco_2 IN PROGRAM sapfmmex USING 'ME' '109'."686022
CASE sy-subrc. "686022
WHEN 02. "686022
MESSAGE e109(me) RAISING failed. "686022
ENDCASE. "686022
WHEN 7. " MESSAGE e110(me) raising failed.
PERFORM enaco_2 IN PROGRAM sapfmmex USING 'ME' '110'."686022
CASE sy-subrc. "686022
WHEN 02. "686022
MESSAGE e110(me) RAISING failed. "686022
ENDCASE. "686022
*>>>> END OF INSERTION <<<<<<
...
*&--------------------------------------------------------------------*
比较遗憾的地方是,这个代码修正对于ECC的几乎全部版本和R3版本都有效;但对于S/4 HANA是无效的;当然可以参照这些修改点,在S/4里进行手工调整,一样也能达到效果;不过,安全起见,最好通过其他的办法来“曲线救国”了;
通过启用PR的更改BADI增强,判断当执行取消下达策略的时候,是否该PR已经存在参考的PO数据,且PO没有被冻结或删除;此时通过对应的报错(甚至直接报ME 110消息)消息即可实现相同的控制逻辑;
以上为本章的全部内容,希望对小伙伴们有帮助;