前言
最近做了一个价格参数增强,没有相应的二代增强点,要使用到BADI:ME_PROCESS_PO_CUST。增强逻辑也并不复杂,只是单纯的对输入价格参数做一个校验,然后提示错误消息。不过问题就来了,在实际测试的过程中,错误消息也出现了,也保存在了上面的消息池里,但是当我们第二次输入正确的消息时候,系统并没有覆盖上面的错误消息,从而导致订单无法保存。
取数逻辑
-
屏幕增强:
在物料主数据维护时,采购视图中增加价格参数MARC- ZJGCS字段。字段信息更新到MARC表中;
-
取数逻辑增强:
*信息记录EKPO-INFNR无值,且价格参数MARC-ZJGCS有值才使用此增强。
判断屏幕信息记录EKPO-INFNR是否有值。
*若信息记录EKPO-INFNR有值,不走此增强。
若信息记录EKPO-INFNR无值,根据屏幕物料EKPO-MATNR_ 工厂EKPO-WERKS=MARC-MATNR_ MARC- WERKS取价格参数MARC-ZJGCS ,判断价格参数MARC- ZJGCS是否有值。
*若MARC- ZJGCS无值不走此增强。
若MARC-ZJGCS有值,MARC- ZJGCS=EINA -MATNR取EINA -LOEKZ,判断EINA -LOEKZ是否为X。
若EINA-LOEKZ=X,提示错误消息“采购信息记录已被删除”。
若EINA-LOEKZ 不等于“X”,MARC- ZJGCS=EINA-MATNR取EINA- INFNR,EINA- INFNR= EINE-INFNR、屏幕EKKO-EKORG=EINE -EKORG、EKPO- PSTYP =EINE - ESOKZ 、EKPO-WERKS=EINE-WERKS取EINE-LOEKZ。判断EINE-LOEKZ是否为X。
若EINE-LOEKZ=X,提示错误消息“采购组织价格记录已被删除”。
若EINE-LOEKZ不等于X,MARC- ZJGCS=A017 -MATNR 、EKKO-EKORG=A017-EKORG、EKPO- PSTYP =A017 - ESOKZ 、EKPO-WERKS=A017-WERKS、EKKO-BEDAT在A017-DATAB_A017-DATBI中,取A017-KNUMH。A017-KNUMH=KONP-KNUMH取KONP-KBETR给EKPO-NETPR赋值、KONP- KPEIN给EKPO-PEINH赋值、KONP-KMEIN给EKPO-BPRME赋值。
屏幕净价EKPO-NETPR字段可进行修改, 按回车或保存时屏幕订单金额EKPO- KBETR与KONP-KBETR进行比较,只可小于等于。否则报错“净价大于采购信息记录价格”。
-
价格控制增强:
采购订单价格带出后可进行修改。判断屏幕信息记录EKPO-INFNR是否有值,若有值才使用此增强。
若EKPO-INFNR有值,EKPO-MATNR=A017 -MATNR、EKKO-LIFNR =A017 -LIFNR、EKKO-EKORG=A017-EKORG、EKPO- PSTYP =A017 - ESOKZ 、EKPO-WERKS=A017-WERKS、且EKKO-BEDAT在A017-DATAB_A017-DATBI中,取A017-KNUMH。A017-KNUMH=KONP-KNUMH,取KONP-KBETR,按回车或保存时屏幕订单金额EKPO- KBETR与KONP-KBETR进行比较,只可小于等于。否则报错“净价大于采购信息记录价格”。
问题截图
源代码
METHOD IF_EX_ME_PROCESS_PO_CUST~PROCESS_ITEM.
DATA: OBJ_HEADER TYPE REF TO IF_PURCHASE_ORDER_MM,
RE_HEADER TYPE MEPOHEADER,
RE_ITEM TYPE MEPOITEM,
EX_CONDITIONS TYPE TABLE OF KOMV,
LS_CONDITIONS TYPE KOMV.
DATA: WA_LIFNR TYPE MEPOHEADER-LIFNR,
WA_EKORG TYPE MEPOHEADER-EKORG,
WA_BEDAT TYPE MEPOHEADER-BEDAT.
DATA: WA_MATNR TYPE MEPOITEM-MATNR,
WA_NETPR TYPE MEPOITEM-NETPR,
WA_WERKS TYPE MEPOITEM-WERKS,
WA_PSTYP TYPE MEPOITEM-PSTYP.
DATA: LT_MARC TYPE TABLE OF MARC,
LS_MARC TYPE MARC.
DATA: LV_ZJGCS TYPE MARC-ZJGCS,
LV_LOEKZ TYPE EINA-LOEKZ,
LV_INFNR TYPE EINA-INFNR,
LV_EKORG TYPE EINE-EKORG,
LV_EBELN TYPE EKKO-EBELN,
LV_BEDAT TYPE EKKO-BEDAT,
LV_PSTYP TYPE EKPO-PSTYP,
LV_WERKS TYPE EKPO-WERKS,
LV_LOEKZ2 TYPE EINE-LOEKZ,
LV_KNUMH TYPE A017-KNUMH,
LV_KBETR TYPE KONP-KBETR,
LV_PEINH TYPE KONP-KPEIN,
LV_BPRME TYPE KONP-KMEIN.
DATA: LV_DUMMY TYPE C LENGTH 128.
DATA: LT_EVENTS TYPE MMPUR_EVENT_LIST.
DATA: LS_EVENT TYPE MMPUR_EVENT_ENTRY.
DATA: LO_BUSINESS_OBJECT TYPE REF TO IF_MESSAGE_OBJ_MM.
INCLUDE MM_MESSAGES_MAC. "useful macros for message handling
OBJ_HEADER = IM_ITEM->GET_HEADER( ).
RE_HEADER = OBJ_HEADER->GET_DATA( ).
RE_ITEM = IM_ITEM->GET_DATA( ).
CALL METHOD IM_ITEM->GET_CONDITIONS
IMPORTING
EX_CONDITIONS = EX_CONDITIONS.
*—取出屏幕字段赋值
WA_EKORG = RE_HEADER-EKORG. "采购组织
WA_LIFNR = RE_HEADER-LIFNR. "供应商
WA_BEDAT = RE_HEADER-BEDAT. "采购凭证日期
WA_MATNR = RE_ITEM-MATNR. "物料号
WA_WERKS = RE_ITEM-WERKS. "工厂
WA_PSTYP = RE_ITEM-PSTYP. "项目分配类别
IF RE_ITEM-INFNR IS INITIAL.
SELECT SINGLE ZJGCS INTO LV_ZJGCS FROM MARC WHERE MATNR = WA_MATNR
AND WERKS = WA_WERKS.
IF LV_ZJGCS IS NOT INITIAL.
SELECT SINGLE LOEKZ INTO LV_LOEKZ FROM EINA WHERE MATNR = LV_ZJGCS.
IF LV_LOEKZ = 'X'.
*— MESSAGE ‘采购信息记录已被删除’ TYPE ‘E’.
MESSAGE E303(ME) WITH TEXT-002 SPACE INTO LV_DUMMY.
MMPUR_CONTEXT MMCNT_USER_EXIT.
MMPUR_MESSAGE SY-MSGTY SY-MSGID SY-MSGNO
SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
CALL METHOD IM_ITEM->INVALIDATE( ).
ELSE.
*— 清空消息先找消息ID
CALL METHOD CL_MESSAGE_HANDLER_MM=>GET_HANDLER
IMPORTING
EX_HANDLER = GL_MESSAGE_HANDLER.
CALL METHOD GL_MESSAGE_HANDLER->GETLIST
IMPORTING
EX_EVENTS = LT_EVENTS.
LOOP AT LT_EVENTS INTO LS_EVENT.
*— check context
IF LS_EVENT-CONTEXT = MMCNT_USER_EXIT.
*— remove message
LO_BUSINESS_OBJECT = LS_EVENT-BUSINESS_OBJ.
CALL METHOD GL_MESSAGE_HANDLER->REMOVE_BY_BO
EXPORTING
IM_BUSINESS_OBJ = LO_BUSINESS_OBJECT
IM_CONTEXT = LS_EVENT-CONTEXT.
ENDIF.
ENDLOOP.
SELECT SINGLE INFNR INTO LV_INFNR FROM EINA WHERE MATNR = LV_ZJGCS.
LV_EKORG = WA_EKORG.
LV_BEDAT = WA_BEDAT.
LV_PSTYP = WA_PSTYP.
LV_WERKS = WA_WERKS.
SELECT SINGLE LOEKZ INTO LV_LOEKZ2 FROM EINE WHERE ESOKZ = LV_PSTYP
AND WERKS = LV_WERKS
AND EKORG = LV_EKORG
AND INFNR = LV_INFNR.
IF LV_LOEKZ2 = 'X'.
*— MESSAGE ‘采购组织价格记录已被删除’ TYPE ‘E’.
MESSAGE E303(ME) WITH TEXT-003 SPACE INTO LV_DUMMY.
MMPUR_CONTEXT MMCNT_USER_EXIT.
MMPUR_MESSAGE SY-MSGTY SY-MSGID SY-MSGNO
SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
CALL METHOD IM_ITEM->INVALIDATE( ).
ELSE.
*— 清空消息
CALL METHOD CL_MESSAGE_HANDLER_MM=>GET_HANDLER
IMPORTING
EX_HANDLER = GL_MESSAGE_HANDLER.
CALL METHOD GL_MESSAGE_HANDLER->GETLIST
IMPORTING
EX_EVENTS = LT_EVENTS.
LOOP AT LT_EVENTS INTO LS_EVENT.
*— check context
IF LS_EVENT-CONTEXT = MMCNT_USER_EXIT.
*— remove message
LO_BUSINESS_OBJECT = LS_EVENT-BUSINESS_OBJ.
CALL METHOD GL_MESSAGE_HANDLER->REMOVE_BY_BO
EXPORTING
IM_BUSINESS_OBJ = LO_BUSINESS_OBJECT
IM_CONTEXT = LS_EVENT-CONTEXT.
ENDIF.
ENDLOOP.
SELECT SINGLE KNUMH INTO LV_KNUMH FROM A017 WHERE MATNR = LV_ZJGCS
AND EKORG = LV_EKORG
AND ESOKZ = LV_PSTYP
AND WERKS = LV_WERKS
AND ( DATAB < LV_BEDAT OR DATAB = LV_BEDAT )
AND ( DATBI > LV_BEDAT OR DATBI = LV_BEDAT ).
IF SY-SUBRC = 0.
SELECT SINGLE KBETR INTO LV_KBETR FROM KONP WHERE KNUMH = LV_KNUMH.
SELECT SINGLE KPEIN INTO LV_PEINH FROM KONP WHERE KNUMH = LV_KNUMH.
SELECT SINGLE KMEIN INTO LV_BPRME FROM KONP WHERE KNUMH = LV_KNUMH.
RE_ITEM-NETPR = LV_KBETR.
RE_ITEM-PEINH = LV_PEINH.
RE_ITEM-BPRME = LV_BPRME.
CALL METHOD IM_ITEM->SET_DATA
EXPORTING
IM_DATA = RE_ITEM.
ENDIF.
ENDIF.
ENDIF.
ENDIF.
ENDIF.
IF RE_ITEM-INFNR IS INITIAL.
SELECT SINGLE ZJGCS INTO LV_ZJGCS FROM MARC WHERE MATNR = WA_MATNR
AND WERKS = WA_WERKS.
IF LV_ZJGCS IS NOT INITIAL.
READ TABLE EX_CONDITIONS INTO LS_CONDITIONS WITH KEY KSCHL = 'PBXX'.
WA_NETPR = LS_CONDITIONS-KBETR.
*— SELECT SINGLE ZJGCS INTO LV_ZJGCS FROM MARC WHERE MATNR = WA_MATNR
*— AND WERKS = WA_WERKS.
SELECT SINGLE INFNR INTO LV_INFNR FROM EINA WHERE MATNR = LV_ZJGCS.
LV_EKORG = WA_EKORG.
LV_BEDAT = WA_BEDAT.
LV_PSTYP = WA_PSTYP.
LV_WERKS = WA_WERKS.
*— SELECT SINGLE LOEKZ INTO LV_LOEKZ2 FROM EINE WHERE ESOKZ = LV_PSTYP
*— AND WERKS = LV_WERKS
*— AND EKORG = LV_EKORG
*— AND INFNR = LV_INFNR.
SELECT SINGLE KNUMH INTO LV_KNUMH FROM A017 WHERE MATNR = LV_ZJGCS
AND EKORG = LV_EKORG
AND ESOKZ = LV_PSTYP
AND WERKS = LV_WERKS
AND ( DATAB < LV_BEDAT OR DATAB = LV_BEDAT )
AND ( DATBI > LV_BEDAT OR DATBI = LV_BEDAT ).
SELECT SINGLE KBETR INTO LV_KBETR FROM KONP WHERE KNUMH = LV_KNUMH.
IF SY-SUBRC = 0.
IF WA_NETPR > LV_KBETR.
MESSAGE E303(ME) WITH TEXT-001 SPACE INTO LV_DUMMY.
MMPUR_CONTEXT MMCNT_USER_EXIT.
MMPUR_MESSAGE SY-MSGTY SY-MSGID SY-MSGNO
SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
CALL METHOD IM_ITEM->INVALIDATE( ).
ELSE.
CALL METHOD CL_MESSAGE_HANDLER_MM=>GET_HANDLER
IMPORTING
EX_HANDLER = GL_MESSAGE_HANDLER.
CALL METHOD GL_MESSAGE_HANDLER->GETLIST
IMPORTING
EX_EVENTS = LT_EVENTS.
LOOP AT LT_EVENTS INTO LS_EVENT.
*— check context
IF LS_EVENT-CONTEXT = MMCNT_USER_EXIT.
*— remove message
LO_BUSINESS_OBJECT = LS_EVENT-BUSINESS_OBJ.
CALL METHOD GL_MESSAGE_HANDLER->REMOVE_BY_BO
EXPORTING
IM_BUSINESS_OBJ = LO_BUSINESS_OBJECT
IM_CONTEXT = LS_EVENT-CONTEXT.
ENDIF.
ENDLOOP.
ENDIF.
ENDIF.
ENDIF.
ELSE.
READ TABLE EX_CONDITIONS INTO LS_CONDITIONS WITH KEY KSCHL = 'PB00'.
WA_NETPR = LS_CONDITIONS-KBETR.
SELECT SINGLE INFNR INTO LV_INFNR FROM EINA WHERE MATNR = WA_MATNR.
LV_EKORG = WA_EKORG.
LV_BEDAT = WA_BEDAT.
LV_PSTYP = WA_PSTYP.
LV_WERKS = WA_WERKS.
SELECT SINGLE KNUMH INTO LV_KNUMH FROM A017 WHERE MATNR = WA_MATNR
AND LIFNR = WA_LIFNR
AND EKORG = LV_EKORG
AND ESOKZ = LV_PSTYP
AND WERKS = LV_WERKS
AND ( DATAB < LV_BEDAT OR DATAB = LV_BEDAT )
AND ( DATBI > LV_BEDAT OR DATBI = LV_BEDAT ).
SELECT SINGLE KBETR INTO LV_KBETR FROM KONP WHERE KNUMH = LV_KNUMH.
IF SY-SUBRC = 0.
IF WA_NETPR > LV_KBETR.
MESSAGE E303(ME) WITH TEXT-001 SPACE INTO LV_DUMMY.
MMPUR_CONTEXT MMCNT_USER_EXIT.
MMPUR_MESSAGE SY-MSGTY SY-MSGID SY-MSGNO
SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
CALL METHOD IM_ITEM->INVALIDATE( ).
ELSE.
CALL METHOD CL_MESSAGE_HANDLER_MM=>GET_HANDLER
IMPORTING
EX_HANDLER = GL_MESSAGE_HANDLER.
CALL METHOD GL_MESSAGE_HANDLER->GETLIST
IMPORTING
EX_EVENTS = LT_EVENTS.
LOOP AT LT_EVENTS INTO LS_EVENT.
*— check context
IF LS_EVENT-CONTEXT = MMCNT_USER_EXIT.
*— remove message
LO_BUSINESS_OBJECT = LS_EVENT-BUSINESS_OBJ.
CALL METHOD GL_MESSAGE_HANDLER->REMOVE_BY_BO
EXPORTING
IM_BUSINESS_OBJ = LO_BUSINESS_OBJECT
IM_CONTEXT = LS_EVENT-CONTEXT.
ENDIF.
ENDLOOP.
ENDIF.
ENDIF.
ENDIF.
ENDMETHOD.
问题解决
上面是问题已经解决了的代码,其中:注释部分是我之前用的MESSAGE ’ ’ TYPE ‘E’ 方法来展示错误信息。 改之后的信息处理逻辑大致是调用此BAPI中的方法,我们来找到错误消息的ID,然后清空即可。具体方法看上述MESSAGE部分代码。