Skip to Content
Author's profile photo Former Member

UPDATE using CRM_ORDER_MAINTAIN simple example (for those new to CRM and/or ABAP)

In a previous blog http://scn.sap.com/community/crm/blog/2013/02/07/crmorderread-simple-example-for-those-new-to-crm-andor-abap I gave a very simple example of how to use CRM_ORDER_MAINTAIN to create a new order.

This blog will show you how to UPDATE an order in CRM using ABAP.
I’ve tried to make this as simple as possible but while including the most important (useful) information.
In this example I will only update the orderadm and opport (opportunity) tables.

include crm_object_names_con.
  data:
  lt_opport_h        type crmt_opport_h_comt,
  ls_opport_h        type line of crmt_opport_h_comt,
  lt_orderadm_h      type  crmt_orderadm_h_comt,
  ls_orderadm_h      type  crmt_orderadm_h_com,
*Other important things
   lt_input_fields    type  crmt_input_field_tab,
   ls_input_fields    type  crmt_input_field,
   lt_nametab         type  crmt_input_field_names_tab,
   ls_nametab         type  crmt_input_field_names,
   lt_save_guid       type  crmt_object_guid_tab,
   ls_save_guid       type  crmt_object_guid,
   lt_saved_objects   type  crmt_return_objects,
   ls_saved_objects   type  crmt_return_objects_struc,
   lv_lin             type   i,
   lv_order_object_id type  crmt_object_id,
   lv_order_object_guid  type  crmt_object_guid32.
* 1. Update the description of the opportunity
clear: ls_nametab, lt_nametab[],
          ls_input_fields.
    ls_orderadm_h-description                = ‘this is the new description’.
    ls_nametab                               = 'DESCRIPTION'.
    append ls_nametab to lt_nametab.
*** for help on how to change a CHAR32 to a RAW16 see my CRM_ORDER_READ blog ***
    ls_orderadm_h-guid                    = ‘this is the GUID type RAW16’.
    append ls_orderadm_h to lt_orderadm_h.
    ls_input_fields-ref_kind = 'A'.
    ls_input_fields-ref_guid = ‘this is the GUID again, in RAW16’.
    ls_input_fields-objectname = 'ORDERADM_H'.
    ls_input_fields-field_names[] = lt_nametab[].
    insert ls_input_fields into table lt_input_fields.
* 2. Update the opportunity data in opport_h table – update the current phase and end date
  clear: ls_nametab, lt_nametab[], ls_input_fields.
    ls_opport_h-curr_phase                 = ‘code for new sales stage’.
    ls_nametab               = 'CURR_PHASE'.
    append ls_nametab to lt_nametab.
    ls_opport_h-expect_end                  = ‘new date for expected end date’.
    ls_nametab              = 'EXPECT_END'.
    append ls_nametab to lt_nametab.
ls_opport_h-ref_guid                    = ‘this is the GUID again, in RAW16’.
    append ls_opport_h to lt_opport_h.
    ls_input_fields-ref_guid        = ‘this is the GUID again, in RAW16’.
    ls_input_fields-ref_kind        = 'A'.
    ls_input_fields-objectname      = 'OPPORT_H'.
    ls_input_fields-field_names[]   = lt_nametab[].
    insert ls_input_fields into table lt_input_fields.
* 3. DONE, call CRM_ORDER_MAINTAIN on this information
call function 'CRM_ORDER_MAINTAIN'
      exporting
        it_opport_h       = lt_opport_h
      importing
        et_exception      = lt_exception1
      changing
        ct_orderadm_h     = lt_orderadm_h
        ct_input_fields   = lt_input_fields
      exceptions
        error_occurred    = 1
        document_locked   = 2
        no_change_allowed = 3
        no_authority      = 4
        others            = 5.
    case sy-subrc.
      when 0.
        ls_save_guid = iv_guid.
        append ls_save_guid to lt_save_guid.
endcase.
* 4. SAVE the changes (all updates must be saved and committed before they change in CRM)
    call function 'CRM_ORDER_SAVE'
      exporting
        it_objects_to_save = lt_save_guid
      importing
        et_saved_objects   = lt_saved_objects
      exceptions
        document_not_saved = 1
        others             = 2.
    case sy-subrc.
      when '0'.
        clear lv_lin.
        describe table lt_saved_objects lines lv_lin.
        if lv_lin = 1.
          read table lt_saved_objects into ls_saved_objects index 1.
          lv_order_object_guid = ls_saved_objects-guid.
          lv_order_object_id   = ls_saved_objects-object_id.
* 5. Call the function to COMMIT the changes to CRM.
          call function 'BAPI_TRANSACTION_COMMIT'.
        endif.
    endcase.
*DONE, your opportunity has now been updated.

Assigned Tags

      22 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Former Member
      Former Member

      Hello,

      Can i have an example for creating contract (items and header) with CRM_ORDER_MAINTAIN.

      Thanks in advance.

      Best regards,

      S.

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Just typing up an example for you. 
      I will POST it here as soon as I've got one together 🙂

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Hi MZK Sanaa,

      Here is some code which I hope will help you:

      The structure needed in the crm_order_maintain call are:

      Exporting "IT_SCHEDLIN_I" (for the quantities)
      Changing "CT_INPUT_FIELDS" (for the fields you're populating) and "CT_ORDERADM_I" (the actual items)

      How to populate these tables (this should give the right idea):

        call function 'CRM_INTLAY_GET_HANDLE'
          importing
            ev_handle = ref_handle.

        call function 'CRM_INTLAY_GET_HANDLE'
          importing
            ev_handle = parent_handle.

         clear: ls_orderadm_i, ls_nametab.

          ls_orderadm_i-handle = parent_handle. "or ref_handle?
          ls_orderadm_i-header = iv_header_guid. "proposal/contract GUID
          ls_orderadm_i-product = is_package-product. "GUID of the product (see table comm_ta_r3_id)
          ls_orderadm_i-mode = 'A'.
          append ls_orderadm_i to lt_orderadm_i.

          ls_nametab = 'MODE'.
          append ls_nametab to lt_nametab.
          ls_nametab = 'PRODUCT'.
          append ls_nametab to lt_nametab.

      * pop lt_input_fields now
          ls_input_fields-ref_handle = parent_handle.
          ls_input_fields-objectname = 'ORDERADM_I'.
          ls_input_fields-field_names[] = lt_nametab[].
          insert ls_input_fields into table lt_input_fields.

      *  QUANTITY
          clear: ls_orderadm_i, ls_nametab, lt_nametab[], ls_input_fields.
          ls_schedlines-quantity = is_package-quantity.
          ls_schedlines-mode = 'A'.
          append ls_schedlines to lt_schedlines.

          ls_schedlin_i-ref_handle = parent_handle.
          ls_schedlin_i-schedlines = lt_schedlines.
          append ls_schedlin_i to lt_schedlin_i.

          ls_nametab = 'QUANTITY'.
          append ls_nametab to lt_nametab.

      * pop lt_input_fields now
          ls_input_fields-ref_handle = parent_handle.
          ls_input_fields-objectname = 'SCHEDLIN'.
          ls_input_fields-ref_kind = 'B'.
          ls_input_fields-field_names[] = lt_nametab[].
          insert ls_input_fields into table lt_input_fields.

      call function 'CRM_ORDER_MAINTAIN'
            exporting
              it_schedlin_i     = lt_schedlin_i
            changing
           ct_orderadm_i     = lt_orderadm_i
              ct_input_fields   = lt_input_fields
            exceptions
              error_occurred    = 1
              document_locked   = 2
              no_change_allowed = 3
              no_authority      = 4
              others            = 5.

      I hope this is helpful - after the order_maintain, call CRM_ORDER_SAVE and BAPI_TRANSACTION_COMMIT

      Let me know how you get along with this,

      Lindsay

      Author's profile photo Former Member
      Former Member

      Thank you for your reply Lindsay.

      This example may help me to resolve my issue.

      Best regards,

      Sanaa

      Author's profile photo Former Member
      Former Member

      Hi Lindsay:

      I love that attitude towards other people.  Somebody who after being sacrificed digging to get to know something, is willing to share.  Thank you very much indeed. 

      Lindsay this is part out of this topic, but do you happen to have any experience with SAP workflow?  We are trying to use WF to work with Business Object BUS2000116,  aswe want to create a WF task (item) to be assigned to users (Agents).   So far we have been able to use your function to read the business transaction (we already had another way of reading the data, but CRM_ORDER_READ is the way to go to make it generic and we had no clue how to use it as ABAP is not my main area of expertise).

      We also use BRFPlus to retrieve some HR data related to one of the BPs actor of the Business Transaction;  Evaluation paths to obtain the list of the so called Agents and also a Rule to retrieve those agents, etc.  So far, we are almost ready, but the problem is that SAP delivers an example WF related for ChaRM for BO BUS2000116 that uses Method ChangeWithDialogAsyn to create the task, but the method does not necessarily apply to what we need.  In other words, we need to create our own method that will create the task to be delivered to the Agents' worklist.

      Once all that is complete our goal is to publish it in SCN as one of the big challenges for people using SAP CHaRM has been the ability of sending multiple e-mails or tasks to Agents.  I believe that once many understand WF applied to CHaRM, there is going to be a lot of freedom for many people to adapt any potential scenario.

      We are still investigation on our side, but seeing your disposition, any help is appreciated.   

      Regards,

      Juan

      Author's profile photo Stephen Johannes
      Stephen Johannes

      You might want to consider posting your comment as a question so it gets more attention instead.  However if you need a different method on a existing business object you can subtype the existing business object and use delegation to replace the parent BUS2000116 with your new subtype that contains your custom method.  That's how I would do it in a CRM based system when I need to add a new attribute or method to an existing BUS2000xxx business object.  The nice part about delegation is that all the other event listening etc will still apply so you don't have to develop a new business object from scratch.

      Take care,

      Stephen

      Author's profile photo Former Member
      Former Member

      Many thanks Stephen.

      Good point that invites me to clarify.  We already have a subtype and the proper delegation setup.  No problem with that.

      We are just looking for an ABAP (BOR) example ofa method that creates a WF task (item) for an Agent.  A method associated to any CRM Business Object BUS2001* will do the work.  Why BUS20001* in particular?  Because most of the Business Objects use WF related methods that call transactions, so when the Agent gets the workflow item in the worklist, in order to process it, a transaction gets launched.  In the case of BUS20001*, the methods are related to WEB UI processing, not transactions.

      The approach for creating the WF task is different when using WEB UI.   

      We understandthe task creates an instance linkage in table SWFDVEVTY1 (transaction SWE3), associating the Business Transaction GUID to an event.  Once the event gets triggered (we know how to do that), as per WF task outcome, the created entry in SWFDVEVTY1 is supposed to be remove and the WF continues to the next step.

      Almost all pieces together except the one that tells how to create the task in a BOR method.

      Regards,

      Juan

      Author's profile photo Former Member
      Former Member

      Good day:

      For the records, the already delivered method BUS2000116.ChangeWithDialogAsyn does the work.    We did not have to create a new method.  The issue we had is with the multiple condition we were using.

      My apologies for the inconvenience.

      Juan

      PS.  The documentation of all what we did will be posted soon.  Only one piece to go now that the workflow is working fine.

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Hi Juan,

      I'm so sorry it has taken me this long to reply to your messages, and I apologise for not being able to help! Coincidentally I have just now been learning about workflows myself, and working with them for the last 4 months, it's all fairly new to me too so I will be interested to see your solution!

      Thank you,

      Lindsay

      Author's profile photo Former Member
      Former Member

      Hi Lindsay:

      We are on the same boat.  With all the struggles we had for months to sort things out and put all the scenario together, leaning towards your approach of sharing knowledge, we decided to write a blog to explain different areas of expertise involved in our solution.

      The initial blog link is http://scn.sap.com/community/it-management/alm/solution-manager/blog/2014/01/21/sap-crmsolman-charm-multiple-target-agents-via-sap-workflow--minimal-abap-development

      Is quite basic honestly, but who knows who is going to run into it, so we can not assume.

      Part #4 has some bibliography at the end and some links.

      No problem for the lack of time Lindsay. We all are on the same boat. 

      Regards,

      Juan Carlos

      Author's profile photo Former Member
      Former Member

      Hi lindsay Thank you a lot for the sharing. Please i have an issue about the same program if i make a loop to mass update the opportunities. the program only update one opportunity How can i transform your program to make it valid for mass opportunities update ? thank you Best regards

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Hi Akrem,

      I haven't done this myself, but off the top of my head the way to perform mass updates is to do exactly as you see in this example here, but add more values to the internal tables being passed into the ORDER_MAINTAIN function - which are all related by their GUIDs back to an entry in the header table (OREDADM_H). Does this make sense? Let me know how you get on 🙂

      The best way to find out for sure would be to put a break point in CRM_ORDER_MAINTAIN and then perform a mass update through the CRM_UI, and see what parameters it passes in.

      Thanks for you question, I hope this help,

      Lindsay

      Author's profile photo Krishna Acharyas
      Krishna Acharyas

      Hi Lindsay ,

      can you help me in creating Service request using CRM_ORDER_MAITAIN (parameters to be passed )and save..

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Hi Krishna,

      My advice would be this: set a break-point (use BP) in CRM_ORDER_MAINTAIN and then create the service request as you would, in a non-ABAP way (I imagine using the CRM_UI web interface?)

      When it hits the BP you will see what tables are populated and how.

      Sometimes the standard SAP way of creating things will in-fact call this FM multiple times, to add different bits to the object each time, but this can usually be condensed into one call, by taking all the inputs from the various calls, and passing them in in one go.

      Sorry I can't be more help - I haven't' created a service request this way yet.

      But once you set a break point and see how it works, it should be come clearer how to proceed 🙂

      Author's profile photo Krishna Acharyas
      Krishna Acharyas

      Hi Lindsay Stanger,

                                 thanks For replay..., Well done like that only and passed values but itn's not working you can see my discussion thread.Re: Creating Service Order  in SAP CRM. 

      Author's profile photo Praveen Nenawa
      Praveen Nenawa

      Hi Lindsay,

      I was looking for such a post from quite a few days .

      Thanks For sharing .

      Author's profile photo Former Member
      Former Member

      Hi Lindsay,

      First of all thank you for making life easier for beginners of SAP CRM. Can you please exaplin the tables that you have used and why have you used them ? i'm unable to find much on the tables that you have used. Are those custom tables or predefned ones?

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Hi Rahul,

      The tables that are used in the ABAP above are the standard importing tables used by the function-module CRM_ORDER_MAINTAIN. None of the ones specified are custom.

      For example: "lt_orderadm_h      type  crmt_orderadm_h_comt" this local table which I use is based on the database table CRMD_ORDERADM_H, the order header data is stored.

      If you look at the Function Module and look under the Import tab you will see descriptions beside most of the importing parameters to tell you what these tables are about.

      My best advice if you are looking to understand this function module better is to set a breakpoint in the FM, and then make a change to an order (opportunity, lead, sales document) - and see what tables are populated when the debug session opens.

      I hope this is helpful to you.

      Thank you for your comments,

      Lindsay

      Author's profile photo Stephen Johannes
      Stephen Johannes

      Rahul,

      If you want a very quick overview take a look here:

      http://wiki.scn.sap.com/wiki/display/CRM/CRM+Business+Transactions

      There are other resources available on the topic if you do a quick search.

      Take care,

      Stephen

      Author's profile photo Girish Goyal
      Girish Goyal

      Lindsay,

      I have some Itab coming from a process type of quote coming from crm_order_read need to insert into sales order. I need to insert those itab lines into sales order line items how will I do it with crm_order_maintain please let me know some example of it .

      Regards,

      Girish

      Author's profile photo Former Member
      Former Member

      Hi Lindsay,

       

      I am creating Contract using FM CRM_ORDER_MAINTAIN. However my Sold to Party is not getting populated. I am populating Org data, External Reference number. Except sold to part rest of the data is getting populated. Please help.

      Please refer my code:

      *Process Type
        CLEAR ls_orderadm_h.
        ls_orderadm_h-process_type 'ZWN'.
        ls_orderadm_h-mode         = 'A'.
        APPEND ls_orderadm_h TO lt_orderadm_h.

      **Preapre Field list table
        CLEARls_nametab,
               ls_input_fields.
        REFRESH lt_nametab[].
        ls_nametab lc_mode.
        APPEND ls_nametab TO lt_nametab.
        ls_nametab lc_proc_type.
        APPEND ls_nametab TO lt_nametab.
        ls_input_fields-ref_kind lc_a.
        ls_input_fields-objectname 'ORDERADM_H'.
        ls_input_fields-field_names[] lt_nametab[].
        INSERT ls_input_fields INTO TABLE lt_input_fields.

      *Sold-To-Party
        CLEAR ls_partner.
        ls_partner-ref_kind 'A'.
        ls_partner-ref_partner_handle '0001'.
        ls_partner-display_type 'BP'.
        ls_partner-kind_of_entry 'C'.
        ls_partner-no_type 'BP'.
        ls_partner-partner_fct '00000001'.
        ls_partner-partner_no '0001040406'.
        APPEND ls_partner TO lt_partner.

      **Preapre Field list table
        CLEARls_nametab,
               ls_input_fields.
        REFRESH lt_nametab[].
        ls_nametab 'DISPLAY_TYPE'.
        APPEND ls_nametab TO lt_nametab.
        ls_nametab 'KIND_OF_ENTRY'.
        APPEND ls_nametab TO lt_nametab.
        ls_nametab 'NO_TYPE'.
        APPEND ls_nametab TO lt_nametab.
        ls_nametab 'PARTNER_FCT'.
        APPEND ls_nametab TO lt_nametab.
        ls_nametab 'PARTNER_HANDLE'.
        APPEND ls_nametab TO lt_nametab.
        ls_nametab 'PARTNER_NO'.
        APPEND ls_nametab TO lt_nametab.
        ls_input_fields-ref_kind 'A'.
        ls_input_fields-objectname 'PARTNER'.
        ls_input_fields-logical_key '0001'.
        ls_input_fields-field_names[] lt_nametab[].
        INSERT ls_input_fields INTO TABLE lt_input_fields.

        CALL FUNCTION 'CRM_ORDER_MAINTAIN'
         EXPORTING
      it_partner                    lt_partner
      IMPORTING
           et_exception                  lt_exception
      CHANGING
           ct_orderadm_h                 lt_orderadm_h
      ct_input_fields               lt_input_fields
      EXCEPTIONS
           error_occurred                1
           document_locked               2
           no_change_allowed             3
           no_authority                  4
           OTHERS                        5.

       

      IF sy-subrc EQ 0.
          CLEAR ls_orderadm_h.
          READ TABLE lt_orderadm_h INTO ls_orderadm_h INDEX 1.
          ls_save_guid ls_orderadm_h-guid.
          APPEND ls_save_guid TO lt_save_guid.

      CALL FUNCTION 'CRM_ORDER_SAVE'
              EXPORTING
                it_objects_to_save lt_save_guid
      IMPORTING
                et_saved_objects   lt_saved_objects
      EXCEPTIONS
                document_not_saved 1
                OTHERS             2.

      IF sy-subrc EQ '0'.
            CLEAR lv_lin.
            DESCRIBE TABLE lt_saved_objects LINES lv_lin.
            IF lv_lin 1.
              READ TABLE lt_saved_objects INTO ls_saved_objects INDEX 1.
              lv_order_object_guid ls_saved_objects-guid.
              lv_order_object_id   ls_saved_objects-object_id.
      * Call the function to COMMIT the changes to CRM.
              CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
                EXPORTING
                  wait abap_true.

      Author's profile photo Georg Koraev
      Georg Koraev

      Hello together,

      I have problem with CRM_ORDER_SAVE. I use this method at a PPF by saving of orders. The Problem this method will be executed twice, because of my PPF and the SAP standard run of this method. However, the problem that, with my updated data in CRM_ORDER_MAINTAIN method, it will be also updated for example SLA data and it leads to redundant calculation of SLA.

      Any suggestions, how can I implement the logic, without influencing of storing data, which should not be stored.

       

      Thx in advance.

      Best regards

      Georg