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.
data: i_call type CRMT_OBJECT_ID VALUE '7000000941'.
data: ls_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.
Thursday, 29 October 2015
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
*"----------------------------------------------------------------------
*"*"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
*"----------------------------------------------------------------------
data: ls_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(4) ne '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
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:
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.
Subscribe to:
Posts (Atom)