Thursday 29 October 2015

ICT_SERVICE_DESK_API : CRM - Solution Manager - Categorise an Incident without Catalog / CodeGroup / Code combo...

Fully geeking out on CRM at the moment. Present remit is to integrate a third party helpdesk system with our SAP Solution Manager helpdesk... The SAP provided ICT interface is pretty good, but as ever you need to call your friendly neighbourhood ABAPer to finesse it into exactly what you want!

Right now, our config guys have told me that they're reluctant to tie together the Categories to the Catalog / CodeGroup / Code that ICT expects, so I'm having to use an enhancement point to update the Categories on our Helpdesk incidents...

Here's my stub program...

REPORT  YPD_INCIDENT_CATEGORISE.

datai_call type CRMT_OBJECT_ID VALUE '7000000941'.

datals_partner type CRMT_PARTNER_COM,
      lt_partner type CRMT_PARTNER_COMt,
      lt_guid type CRMT_OBJECT_GUID_TAB,
      ls_guid type CRMT_OBJECT_GUID,
      lt_input_fields type CRMT_INPUT_FIELD_TAB,
      ls_input_fields type CRMT_INPUT_FIELD,
      ls_field_names type CRMT_INPUT_FIELD_NAMES,
      lt_field_names TYPE CRMT_INPUT_FIELD_NAMES_TAB,
      lt_orderadm_h TYPE CRMT_ORDERADM_H_COMT,
      ls_orderadm_h type crmt_orderadm_h_com,
      lt_exception type CRMT_EXCEPTION_T,
      lt_sales type CRMT_SALES_COMT,
      ls_sales type CRMT_SALES_COM,
      lt_service_os type CRMT_SRV_OSSET_COMT,
      ls_service_os type CRMT_SRV_OSSET_COM,
      ls_osset type CRMT_SRV_OSSET_COM1,
      ls_subject type CRMT_SRV_SUBJECT_COM,
      LS_GUID16 TYPE guid_16.

CALL FUNCTION 'CRM_ORDERADM_H_GUID_GET_DB'
  EXPORTING
    IV_OBJECT_ID           i_call
  IMPORTING
    ET_GUID                lt_guid
 EXCEPTIONS
   RECORD_NOT_FOUND       1
   OTHERS                 2.

READ TABLE lt_guid into ls_guid INDEX 1.

check ls_guid is not INITIAL.



"Trying to Categorise the call....
ls_service_os-ref_guid ls_guid.
ls_service_os-ref_kind 'A'.

CALL FUNCTION 'GUID_CREATE'
 IMPORTING
    EV_GUID_16       ls_guid16.

ls_subject-ref_guid ls_guid16.
ls_subject-asp_id 'EDENHOUSE SOLUTIONS'.
ls_subject-cat_id 'AIC_CAT01_03_06'.
ls_subject-katalog_type 'D'.

INSERT ls_subject into table ls_osset-subject.

CALL FUNCTION 'GUID_CREATE'
 IMPORTING
    EV_GUID_16       ls_guid16.

ls_osset-ref_guid ls_guid16.
ls_osset-profile_type 'A'.

insert ls_osset  into TABLE ls_service_os-osset.

insert ls_service_os INTO TABLE lt_service_os.

"Do the input fields too...


*ls_input_fields-REF_HANDLE
ls_input_fields-REF_GUID     ls_service_os-ref_guid.
ls_input_fields-REF_KIND     'A'.
ls_input_fields-OBJECTNAME   'SERVICE_OS'.









ls_field_names-fieldname 'ASP_ID'.
INSERT ls_field_names INto table ls_input_fields-FIELD_NAMES.
ls_field_names-fieldname 'CAT_ID'.
INSERT ls_field_names INto table ls_input_fields-FIELD_NAMES.
ls_field_names-fieldname 'CODE'.
INSERT ls_field_names INto table ls_input_fields-FIELD_NAMES.
ls_field_names-fieldname 'CODEGRUPPE'.
INSERT ls_field_names INto table ls_input_fields-FIELD_NAMES.
ls_field_names-fieldname 'KATALOGART'.
INSERT ls_field_names INto table ls_input_fields-FIELD_NAMES.
ls_field_names-fieldname 'MODE'.
INSERT ls_field_names INto table ls_input_fields-FIELD_NAMES.
ls_field_names-fieldname 'REF_GUID'.
INSERT ls_field_names INto table ls_input_fields-FIELD_NAMES.


insert ls_input_fields into TABLE lt_input_fields.

  CALL FUNCTION 'CRM_ORDER_MAINTAIN'
    EXPORTING
*      it_partner                  = lt_partner
       it_service_os               lt_service_os
*      it_sales                    = lt_sales
*      it_service_h                = lt_service_h
  IMPORTING
      ET_EXCEPTION                  lt_exception
    CHANGING
      ct_input_fields              lt_input_fields
    EXCEPTIONS
      error_occurred               1
      document_locked              2
      no_change_allowed            3
      no_authority                 4
      OTHERS                       5.



CALL FUNCTION 'CRM_ORDER_SAVE'
  EXPORTING
    IT_OBJECTS_TO_SAVE           lt_guid
 EXCEPTIONS
   DOCUMENT_NOT_SAVED           1
   OTHERS                       2
          .
IF SY-SUBRC <> 0.
* Implement suitable error handling here
ENDIF.


commit work and wait.


Friday 23 October 2015

UI5 Product Locator App


Was just putting this baby to bed and realised that I'd not blogged it yet!




Anyway, it was a stack of fun to develop, and if anyone wants something like this on their SAP system, get in touch with EdenhouseSolutions!

Wednesday 21 October 2015

CRM Add Partner to Incident

The following function can be used to add bespoke partner functions to SAP CRM Incidents - in this case, a "Requester".
The bit that threw me was the need for a BAPI-Commit after the CRM_ORDER_SAVE; it seems SAP have added another layer of flexibility / complexity


FUNCTION 
ZSHA_ORDER_MAINTAIN_ADD.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     REFERENCE(I_CALL) TYPE  CRMT_OBJECT_ID
*"     REFERENCE(I_REQUESTER) TYPE  CRMT_PARTNER_NO
*"     REFERENCE(I_SOLD_TO) TYPE  CRMT_PARTNER_NO
*"----------------------------------------------------------------------

datals_partner type CRMT_PARTNER_COM,
      lt_partner type CRMT_PARTNER_COMt,
      lt_guid type CRMT_OBJECT_GUID_TAB,
      ls_guid type CRMT_OBJECT_GUID,
      lt_input_fields type CRMT_INPUT_FIELD_TAB,
      ls_input_fields type CRMT_INPUT_FIELD,
      ls_field_names type CRMT_INPUT_FIELD_NAMES,
      lt_field_names TYPE CRMT_INPUT_FIELD_NAMES_TAB,
      lt_orderadm_h TYPE CRMT_ORDERADM_H_COMT,
      ls_orderadm_h type crmt_orderadm_h_com,
      lt_exception type CRMT_EXCEPTION_T.

CALL FUNCTION 'CRM_ORDERADM_H_GUID_GET_DB'
  EXPORTING
    IV_OBJECT_ID           i_call
*   IV_OBJECT_TYPE         =
  IMPORTING
    ET_GUID                lt_guid
 EXCEPTIONS
   RECORD_NOT_FOUND       1
   OTHERS                 2.

READ TABLE lt_guid into ls_guid INDEX 1.

ls_partner-ref_guid ls_guid.
ls_partner-ref_kind 'A'.
ls_partner-ref_partner_handle '0001'.
ls_partner-kind_of_entry 'C'.
ls_partner-partner_fct 'Z0000015'.
ls_partner-partner_no i_requester.
if ls_partner-partner_no(4ne '0000'.
  CONCATENATE '0000' ls_partner-partner_no into ls_partner-partner_no.
endif.

ls_partner-display_type 'BP'.
ls_partner-no_type 'BP'.


append ls_partner to lt_partner.

*ls_input_fields-REF_HANDLE
ls_input_fields-REF_GUID     ls_guid.
ls_input_fields-REF_KIND     'A'.
ls_input_fields-OBJECTNAME   'PARTNER'.
ls_input_fields-LOGICAL_KEY  '0001'.



ls_field_names-fieldname 'DISPLAY_TYPE'.
INSERT ls_field_names INto table ls_input_fields-FIELD_NAMES.
ls_field_names-fieldname 'KIND_OF_ENTRY'.
INSERT ls_field_names INto table ls_input_fields-FIELD_NAMES.
ls_field_names-fieldname 'NO_TYPE'.
INSERT ls_field_names INto table ls_input_fields-FIELD_NAMES.
ls_field_names-fieldname 'PARTNER_FCT'.
INSERT ls_field_names INto table ls_input_fields-FIELD_NAMES.
ls_field_names-fieldname 'PARTNER_NO'.
INSERT ls_field_names INto table ls_input_fields-FIELD_NAMES.

append ls_input_fields to lt_input_fields.



*ls_orderadm_h-guid = ls_guid.
*append ls_orderadm_h to lt_orderadm_h.


  CALL FUNCTION 'CRM_ORDER_MAINTAIN'
    EXPORTING
*      it_activity_h               = lt_activity_h
*      it_appointment              = lt_appointment
*     it_text                      = lt_text
      it_partner                  lt_partner
*      it_service_os               = lt_service_os
*      it_status                   = lt_status
*      it_sales                    = lt_sales
*      it_service_h                = lt_service_h
  IMPORTING
      ET_EXCEPTION                  lt_exception
    CHANGING
*      ct_orderadm_h                = lt_orderadm_h
      ct_input_fields              lt_input_fields
**    CV_LOG_HANDLE                =
**    CT_PARTNER_ATTRIBUTES        =
**    CT_DOC_FLOW                  =
    EXCEPTIONS
      error_occurred               1
      document_locked              2
      no_change_allowed            3
      no_authority                 4
      OTHERS                       5.

CALL FUNCTION 'CRM_ORDER_SAVE'
  EXPORTING
    IT_OBJECTS_TO_SAVE           lt_guid
*   IV_UPDATE_TASK_LOCAL         = FALSE
*   IV_SAVE_FRAME_LOG            = FALSE
*   IV_NO_BDOC_SEND              = FALSE
*   IT_ACTIVE_SWITCH             =
* IMPORTING
*   ET_SAVED_OBJECTS             =
*   ET_EXCEPTION                 =
*   ET_OBJECTS_NOT_SAVED         =
* CHANGING
*   CV_LOG_HANDLE                =
*   CT_NOCHECK_BEFORE_SAVE       =
 EXCEPTIONS
   DOCUMENT_NOT_SAVED           1
   OTHERS                       2
          .
IF SY-SUBRC <> 0.
* Implement suitable error handling here
ENDIF.


commit work and wait.

ENDFUNCTION.

Tuesday 6 October 2015

VB Documentation tool...

I was asked to ensure that the documentation on a program had pseudo-code in it to describe what was going on in...

I had originally cut and pasted the code (lazy, but consistent with what I'd seen from previous documentation on the same project, and also, I got time issues...) which prompted the user to ask for better explanation of what was going on...

The trick for us ABAPers is the balance between the technical and the functional; we have to describe things in English to the Apps guys, and explain things in ABAP to The Computer, and it's often difficult to do both at the same time in a technical spec:

A way of making this easier is to just make sure that every time you output a field name, you output the description as well (and vice versa, but this is less achievable automatically )

The project I'm on is asking for 10 word documents where this is done.

Rather than doing "replace EKPO with EKPO(PO Line Item)" x ten files x 25 different fields, I thought it more prudent to write some code to do it.

Why get a man to do a machine's job?

Anyway, this is some VBScript that will quickly do all the replacements. The fact that it happens slow enough for the eye to see is really satisfying, as it kind of looks like code from films.

Sub Macro2()
'

Dim findandreplace(1, 25) As String

findandreplace(0, 0) = "VBELN"
findandreplace(1, 0) = "VBELN(Sales Document#)"

findandreplace(0, 1) = "posnr"
findandreplace(1, 1) = "POSNR(Line Item#)"

findandreplace(0, 2) = "kunnr"
findandreplace(1, 2) = "KUNNR(Customer#)"

findandreplace(0, 3) = "vkorg"
findandreplace(1, 3) = "VKORG(Sales Org)"

findandreplace(0, 4) = "vtweg"
findandreplace(1, 4) = "VTWEG(Distribution Channel)"

findandreplace(0, 5) = "vbep"
findandreplace(1, 5) = "VBEP(Schedule Line Data)"

findandreplace(0, 6) = "matnr"
findandreplace(1, 6) = "MATNR(Material)"

findandreplace(0, 7) = "lfstk"
findandreplace(1, 7) = "LFSTK(Delivery status)"

findandreplace(0, 8) = "EDATU"
findandreplace(1, 8) = "EDATU(Schedule line date)"

findandreplace(0, 9) = "EZEIT"
findandreplace(1, 9) = "EZEIT(Arrival time)"

findandreplace(0, 10) = "ABGRU"
findandreplace(1, 10) = "ABGRU(Reason for rejection)"

findandreplace(0, 11) = "PARVW"
findandreplace(1, 11) = "PARVW(Partner Function)"

findandreplace(0, 12) = "WERKS"
findandreplace(1, 12) = "WERKS(Plant)"

findandreplace(0, 13) = "VBAP"
findandreplace(1, 13) = "VBAP(SO Line Item)"

findandreplace(0, 14) = "VBAK"
findandreplace(1, 14) = "VBAK(SO Header)"

findandreplace(0, 15) = "LFSTK"
findandreplace(1, 15) = "LFSTK(Delivery Status)"

findandreplace(0, 16) = "WBSTK"
findandreplace(1, 16) = "WBSTK(Total goods movement status)"

findandreplace(0, 17) = "LIFSP"
findandreplace(1, 17) = "LIFSP(Default delivery block)"

findandreplace(0, 18) = "SPRAS"
findandreplace(1, 18) = "SPRAS(Language)"

findandreplace(0, 19) = "VBUK"
findandreplace(1, 19) = "VBUK(Sales Document Admin Data)"

findandreplace(0, 20) = "KNKK"
findandreplace(1, 20) = "KNKK(Customer Credit)"

findandreplace(0, 21) = "LIKP"
findandreplace(1, 21) = "LIKP(SD Document: Delivery Header Data)"

findandreplace(0, 22) = "bolnr"
findandreplace(1, 22) = "BOLNR(Tare/Registration#)"
                     
findandreplace(0, 23) = "makt"
findandreplace(1, 23) = "MAKT(Material Texts)"

findandreplace(0, 24) = "kkber"
findandreplace(1, 24) = "KKBER(Credit Control Area)"

findandreplace(0, 25) = "LFDAT"
findandreplace(1, 25) = "LFDAT(Delivery Date)"


For j = 1 To 25

    Selection.Find.ClearFormatting
    Selection.Find.Replacement.ClearFormatting
    With Selection.Find
        .Text = findandreplace(0, j)
        .Replacement.Text = findandreplace(1, j)
        .Forward = True
        .Wrap = wdFindContinue
        .Format = False
        .MatchCase = False
        .MatchWholeWord = False
        .MatchWildcards = False
        .MatchSoundsLike = False
        .MatchAllWordForms = False
    End With
    Selection.Find.Execute Replace:=wdReplaceAll

Next j



End Sub

Monday 5 October 2015

Status from a Network Order

So I had to map this out for someone... quite straightforward, but might be of use to someone out there!

Here we have Network Order 41000000 which has a variety of Statuses against it:


AUFK doesn’t contain the statuses. To find the statuses, we go via table JEST. JEST is keyed on OBJNR (Object Number) which is a field in AUFK. It’s basically the order number with a prefix.


So a search on JEST for OBJNR = NP000041000000, which yields the following:


Column 3 in this table is whether the status is inactive or not, so we ignore anything with an X in it.

For the internal statuses, we can get the text from table TJ02T :



For the external statuses, we can get the text from table TJ30T.