sunyke 发表于 2015-9-17 13:26:56

【原创】2011.09.18 SAP 订单中修改订单净价

  本文以销售订单为例,说一下如何使用SAP预置的BAPI来更新销售订单(SD)的净价。

1.前提
  首先需要了解一下销售订单所对应的表的关系:
  订单抬头表:VBAK——订单行项目表:VBAP。
  我们所要修改的净价所对应的数据库字段可以在VBAP订单行项目表中找到,具体字段是VBAP~NETPR这个字段。需要注意的是,根据物料的不同,净价所对应的个数也是不同的。我们可以再数据库中找到紧跟着NETPR的一个字段,名称是KPEIN,这个字段的含义就是NETPR所指净价对应的个数,举个例子,如下图的订单,代表的就是这个订单号为554的销售订单,单价为1755.00/100个。因此,在后续的修改价格中,首先要确认订单项目中关于单价和个数的关系。

  另外,我们还要了解一下订单条件的概念,每一个订单的定价都是由各种条件来确定的。例如个数到达100,打7折之类的条件。而我们要修改的则是其最基本得初始净价。使用T-CODE:VA03打开任意一张有行项目的销售订单,并双击一条行项目,进去查看行项目的详细信息。

  进去之后我们可以看到condition的选项卡

  在这边,我们就可以看到关于价格的价格类型了,就是图中所示,描述为Price那一行的Cnty,图中为PR00。这个就称之为Condition Type(条件类型),条件类型决定了条件中价格的计算方式等,基本上每个企业的基本净价的类型都只有一种,例如我图中所示的机器的价格类型,基本类型就为PR00,我们要修改的就是这个行项目,类型为PR00的计划的金额了。
  最后还要了解的就是计划相关的表了:销售订单抬头表:VBAP,计划行表:KONV,关联:VBAP~KNUMV = KONV~KNUMV。
  

2.方法
  步骤1:首先获取到某一个行项目,目的是获取到其行项目号,并进而获取到相对应的计划行。
  步骤2:根据行项目对应的抬头数据,获取到对应的计划行,取得计划行。
  步骤3:根据计划行,填写修改订单BAPI中所需要的CONDITION数据。
  步骤4:调用BAPI修改订单。
  代码如下:



FORM FRM_MAKE_CONDITION USING LW_CONDITION TYPE BAPICOND"BAPI需要配置的CONDITION
LW_CONDITION_X TYPE BAPICONDX "BAPI需要配置的CONDITION_X
LW_VBAP TYPE VBAP."某个销售订单行项目
DATA:   LW_VBAK TYPE VBAK,
LW_KONV TYPE KONV,
LT_KONV TYPE TABLE OF KONV.
SELECT SINGLE * FROM VBAK
INTO CORRESPONDING FIELDS OF LW_VBAK
WHERE VBAK~VBELN EQ LW_VBAP-VBELN.
IF LW_VBAK IS INITIAL.
RETURN .
ENDIF.
"从计划行中取得要修改的计划行
SELECT SINGLE * FROM KONV
INTO CORRESPONDING FIELDS OFLW_KONV
WHERE KONV~KNUMV EQ LW_VBAK-KNUMV
AND KONV~KPOSN EQ LW_VBAP-POSNR
AND KONV~KSCHL EQ 'PR00'.
IF LW_KONV IS INITIAL.
RETURN.
ENDIF.
"修改相应的数据
LW_CONDITION-ITM_NUMBER = LW_KONV-KPOSN.
LW_CONDITION-COND_ST_NO = LW_KONV-STUNR.
LW_CONDITION-COND_COUNT = LW_KONV-ZAEHK.
LW_CONDITION-COND_TYPE = LW_KONV-KSCHL.
LW_CONDITION-CURRENCY = LW_KONV-WAERS.
LW_CONDITION-COND_VALUE = LW_VBAP-NETPR .
LW_CONDITION_X-ITM_NUMBER = LW_KONV-KPOSN.
LW_CONDITION_X-COND_COUNT = LW_KONV-ZAEHK.
LW_CONDITION_X-COND_ST_NO = LW_KONV-STUNR.
LW_CONDITION_X-COND_TYPE = LW_KONV-KSCHL.
LW_CONDITION_X-CURRENCY = 'X'.
LW_CONDITION_X-COND_VALUE = 'X'.
LW_CONDITION_X-UPDATEFLAG = 'U'.
ENDFORM.                  "frm_make_condition

  这个子过程根据传入的行项目结构修改传入的两个BAPI需要参数,我们根据LW_VBAK 中的KNUMV(计划号)字段,LW_VBAP中的POSNR(行项目号)及计划行类型(前述)来获取到计划行,之后填入BAPI所需要的CONDITION字段,填写的内容包括
  ITM_NUMBER:项目号
  COND_ST_NO:步数号,根据取出的条件行获取
  COND_COUNT:条件数,根据取出的条件行获取
  COND_TYPE:条件类型
  CURRENCY:货币类型,注意,这个字段必须输入,否则会照成价格与数量不匹配的问题。
  COND_VALUE:价格,这个就不说了,最重要的字段,也就是我们要改的价格。
  需要注意的是,一般来说,BAPI的调用都会有相应的X字段,也就是说一个CONDITION行会对应一个CONDITION_X行,CONDITION_X表示一些技术选项,例如,所对应的CONDITION是要更新还是要插入,有哪些字段是要更新的。而我们是为了更新价格,因此在CONDITION_X这个结构中,要将对应的UPDATEFLAG设置成X,表示在CONDITION表中对应的那一行,是要更改的。
  反之,如果是要插入,则输入I,删除为D。并且,如果是插入的话,COND_COUNT和COND_COUNT就不用更改了,系统会自动维护。
  在调用完这个子程序后我们获取到了两个结构,一个为CONDITION,一个是对应的CONDITION_X,在调用BAPI之前,我们把这两个结构插入到内表中。

APPEND LW_SO_ORDER_CONDITION TO T_SO_ITEM_CONDITION.
APPEND LW_SO_ORDER_CONDITION_X TO T_SO_ITEM_CONDITION_X.

  最后调用BAPI,更新数据.

    CALL FUNCTION 'BAPI_SALESORDER_CHANGE'
EXPORTING
SALESDOCUMENT               = L_VBELN
*    ORDER_HEADER_IN             =
ORDER_HEADER_INX            = LW_SO_HEAD_X
*    SIMULATION                  =
*    BEHAVE_WHEN_ERROR         = ' '
*    INT_NUMBER_ASSIGNMENT       = ' '
LOGIC_SWITCH                = LW_LOGIC_SWITCH
*    NO_STATUS_BUF_INIT          = ' '
TABLES
RETURN                      = T_RETURN
*   ORDER_ITEM_IN               = T_SO_ITEM
*      ORDER_ITEM_INX            = T_SO_ITEM_X
*    PARTNERS                  =
*    PARTNERCHANGES            =
*    PARTNERADDRESSES            =
*    ORDER_CFGS_REF            =
*    ORDER_CFGS_INST             =
*    ORDER_CFGS_PART_OF          =
*    ORDER_CFGS_VALUE            =
*    ORDER_CFGS_BLOB             =
*    ORDER_CFGS_VK               =
*    ORDER_CFGS_REFINST          =
*      SCHEDULE_LINES            = T_SO_SCHEDULE
*   SCHEDULE_LINESX             = T_SO_SCHEDULE_X
*    ORDER_TEXT                  =
*    ORDER_KEYS                  =
CONDITIONS_IN               = T_SO_ITEM_CONDITION
CONDITIONS_INX            = T_SO_ITEM_CONDITION_X
*    EXTENSIONIN               =
.

  需要注意,在EXPORT参数中,ORDER_HEADER_INX的UPDATEFLAG字段是需要设置的,如同前文所述,更新便设置成U。
  另外,LOGIC_SWITCH字段的PRICING字段也是需要设置的,这个字段代表了价格的更新方式,一般来说设置成G。
  也就是说,在调用这个方法前,需要创建两个结构,并且设置相应的字段吗,设置如下:

LW_SO_HEAD_X-UPDATEFLAG = 'U'.
LW_LOGIC_SWITCH-PRICING = 'G'.
  
  最后才确保BAPI没有出错的情况下,提交事务。

CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'.
  
  自此,销售订单的净价更改完毕。
页: [1]
查看完整版本: 【原创】2011.09.18 SAP 订单中修改订单净价