If you know CMD_EI_API class, you are aware of its power. It's very helpful for the manipulation of customer master data, all master data including contacts. I have played with this class many times and although I got use to the structure of it, I thought one day that it would be handy to have a wrapper or framework to use it. So I've started to build it.

As a result I have now more handy (but not perfect) class to handle the creation or update of customer master data with CMD_EI_API=>MAINTAIN_BAPI method.

The whole source code is available as current version on Github, from where you can instal this class (and all supporting ones) with abapGit https://github.com/fidley/Customers

As there is no much documentation about this class yet, I will extend this article in future with more details, for now just the basics information how to start with it. 

As you can see on the image bellow, there are few methods and attributes there but the constructor is most important, when you will pass the customer number to constructor, then the class will try to read data of existing customer, if not then it will assume that you want to create new customer. 

 

 

The attributes corresponds to the structure of the customer in the CMD_EI_API class, so if you're familiar with it, it will be very easy to understand the logic. Anyway even if you don't know the CMD_EI_API, the names of the attributes and methods should be easy to decode.  Instal it, try to play with it and give me any feedback, here or on Github. Some samples and documentation will come soon.

Contact Persons

Creation of a new contact person:

parameters: p_custom type kna1-kunnr.
try.
    data(customer) = new zcl_cmd_customer( i_customer = p_custom ).
    data(contact) = customer->add_new_contact( ).
    contact->set_addr_lastname( 'LastName' ).
    contact->set_addr_firstname( 'FirstName' ).
    customer->save( ).
catch zcx_cmd_customer.
endtry.

 

Changing of contact person using contact person number:

parameters: p_custom type kna1-kunnr obligatory,
                  p_cont type knvk-parnr obligatory.
try.
    data(customer) = new zcl_cmd_customer( i_customer = p_custom ).
    data(contact) = customer->change_contact( i_contact = p_cont ).
    contact->set_addr_lastname( 'LastName' ).
    contact->set_addr_firstname( 'FirstName' ).
    contact->add_email( This email address is being protected from spambots. You need JavaScript enabled to view it.').
    customer->save( ).
  catch zcx_cmd_customer.
endtry.

 

Changing of contact person using contact person name:

parameters: p_custom type kna1-kunnr obligatory,
                   p_fname  type bapiad3vl-firstname obligatory,
                   p_lname  type bapiad3vl-lastname obligatory.
try.
    data(customer) = new zcl_cmd_customer( i_customer = p_custom ).
    data(contact) = customer->get_contact_by_name(
                    i_firstname      = p_fname
                    i_lastname       = p_lname ).
    contact->set_addr_lastname( 'LastName2' ).
    contact->set_addr_firstname( 'FirstName2' ).
    customer->save( ).
  catch zcx_cmd_customer.
endtry.

 

Deletion of contact person:

parameters: p_custom type kna1-kunnr obligatory,
                   p_cont   type knvk-parnr obligatory.
try.
    data(customer) = new zcl_cmd_customer( i_customer = p_custom ).
    data(contact) = customer->delete_contact( p_cont ).
    customer->save( ).
  catch zcx_cmd_customer.
endtry.

 

Extension of ZCL_CMD_CUSTOMER

Every (almost) company which is using SAP has some custom fields in the customer master data. As this is very specific for each company, there is no easy way to include this kind of fields into the ZCL_CMD_CUSTOMER class. It's even better to keep the clean core functionality away from the extension, as you may have for example different extensions to customer master data on your different instances of ERP.

 

In order to allow you to use ZCL_CMD_CUSTOMER class with the custom fields I've prepared the logic that needs to be used.

  1. You need to create local or global class that will inherit any of the ZCL_CMD_* class (depending which you want to extend).
  2. In the constructor of ZCL_CMD_CUSTOMER fill the I_EXTENSION_CLASSES table with the type of the extension and the name of the class which is extending it.

The type of the extension you can find in ZCL_CMD_EXTENSIONS=>CLASS_EXTENSIONS constant. Such way of creating extensions allows you to do either one or more extensions on the same system.

Please check following test program which shows how to extend ZCL_CMD_CUSTOMER with local class.

 

parameters: p_custom type kna1-kunnr,
                  p_sale   type knvv-vkorg,
                  p_distr  type knvv-vtweg,
                  p_divis  type knvv-spart.

class lcl_customer definition create public inheriting from zcl_cmd_customer.
  public section.
    methods
: constructor importing
                           value(i_customer) type kna1-kunnr optional
                         raising
                           zcx_cmd_customer .
  protected section.
  private section.
endclass.

class lcl_customer implementation.
  method
constructor.
    super->constructor( exporting i_customer = i_customer
                                  i_extension_classes = value #( (  type = zcl_cmd_extensions=>class_extension-sales
                                                                    name = 'LCL_CMD_SALES' ) ) ).
  endmethod.
endclass.

class
lcl_cmd_sales definition create public inheriting from zcl_cmd_sales.
  public section.
    methods
: new_method.
  protected section.
  private section.
endclass.

class
lcl_cmd_sales implementation.
  method
new_method.
  endmethod.
endclass.

start-of-selection.
  try.
      data
(customer) = new lcl_customer( i_customer = p_custom ).
      data(sales_org) = cast lcl_cmd_sales( customer->get_sales_org(
        exporting
          i_sales_org      = p_sale
          i_distr_channel  = p_distr
          i_division       = p_divis
      ) ).
      sales_org->new_method( ).
      customer->save( ).
    catch zcx_cmd_customer.
  endtry.