Cyfloel

从事SAP相关技术顾问工作,BLOG记录了自己遇到的一些问题和一些自己的学习心得,为了能帮助自己,也希望能够帮助到有需要的人。

导航

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

Posted on 2011-09-18 15:07  Cyfloel  阅读(1928)  评论(0编辑  收藏  举报

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

1.前提

首先需要了解一下销售订单所对应的表的关系:

订单抬头表:VBAK——订单行项目表:VBAP。

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

QQ截图20110918142149

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

QQ截图20110918142652

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

QQ截图20110918143049

在这边,我们就可以看到关于价格的价格类型了,就是图中所示,描述为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 OF  LW_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'.

 

自此,销售订单的净价更改完毕。