SAP-samples / btp-bridge-framework

Create a Microsoft Teams extension app to SAP S/4HANA with JSON configuration.
Apache License 2.0
5 stars 5 forks source link

output format of ABAP job (the data format which S/4HANA sends it to event mesh via ABAP Job). #34

Closed ChanchalAgrawalMiku closed 1 year ago

ChanchalAgrawalMiku commented 1 year ago

Hi,

Please share the output format of ABAP job (the data format which S/4HANA sends it to event mesh via ABAP Job).

Br, Chanchal

AFK-Python commented 1 year ago

Hi Chanchal,

The output format should look like this:

{
    "TASK_ID": <task_id_value>,
    "CREATED_BY": "Weikun Liu",
    "CREATED_ON": "AUG092023",
    "CREATER_EMAIL": "creator@something.com",
    "FORWARD": "creator@something.com",
    "PRIORITY": "Medium",
    "USER_ID": <This is Approver's ID in the S/4HANA System>,                                    
    "USER_EMAIL": <This is Approver's Email in the S/4HANA System and MS Teams>,      
    "PO_ID": <po_id_value>,
    "DESCRIPTION": "Approve Purchase Order <po_id_value>",
    "ACTIONS": [
        {
            "ACTION_ID": "0001",
            "ACTION_DESC": "Approve"
        },
        {
            "ACTION_ID": "0002",
            "ACTION_DESC": "Reject"
        }
    ]
}

Best, Alex

ChanchalAgrawalMiku commented 1 year ago

H,

Thank you. ABAP job is correctly giving the above output but getting the following message in Teams bot.

image
  1. is the ABAP output missing with fields named as "Others"?
  2. what value should be in the of the ABAP output?
  3. ABAP job has sent two email ids as below but still it is throwing error as below
"USER_EMAIL": "chanchal.agrawal@xyz.fi, approver@xyz.fi",

"error":"uncaughtException: Cannot read properties of undefined (reading 'split')\nTypeError: Cannot read properties of undefined (reading 'split')\n at /home/vcap/app/router/NotificationRouter.js:21:54\n

  1. what is the output format of the webhook (which is send to backend app)?

Br, Chanchal

AFK-Python commented 1 year ago

Hi Chanchal,

In response to your questions:

  1. There shouldn't be, are you experiencing this?
  2. The value of the task id should be a string of digits, of length 12.
  3. This suggests that the notification router is not receiving the correct JSON object. This error corresponds to: eventData["USER_EMAIL"] = eventData["USER_EMAIL"].split(","); - so it seems that "USER_EMAIL" is undefined. Could you this right before that line of code: console.log(eventData)? Please let me know what that logs back - you should be able to see this in your backend logs in BTP. Note, I would probably add another log statement just above with something unique to find the error easily - another tip is to download the logs, much easier to read and use find and replace that way. I think two email address might be causing the problem, could you try with one?
  4. The output format of the web hook is the same as the ABAP job.

Best, Alex

ChanchalAgrawalMiku commented 1 year ago

Hi Alex,

I added the console.log(eventData) and console.log(notificationConfig).

It seems the output of ABAP job (and webhook) is not properly converting/mapping the values to eventData and notificationConfig. for example: values of fields USER_EMAIL, PO_ID, TASK_ID, etc are not reflecting in eventData and notificationConfig.

Please find below logs.

console.log(eventData)

   2023-08-17T18:42:37.58+0000 [APP/PROC/WEB/0] OUT received evenet data: {}
   2023-08-17T18:42:37.58+0000 [APP/PROC/WEB/0] OUT received evenet data-user email: undefined

console.log(notificationConfig)

   2023-08-17T18:42:37.71+0000 [APP/PROC/WEB/0] OUT received notification config: {
   2023-08-17T18:42:37.71+0000 [APP/PROC/WEB/0] OUT BusinessObjectName: 'PO',
   2023-08-17T18:42:37.71+0000 [APP/PROC/WEB/0] OUT fields: {
   2023-08-17T18:42:37.71+0000 [APP/PROC/WEB/0] OUT ReceiverEmailList: 'USER_EMAIL',
   2023-08-17T18:42:37.71+0000 [APP/PROC/WEB/0] OUT ObjectId: 'PO_ID',
   2023-08-17T18:42:37.71+0000 [APP/PROC/WEB/0] OUT ActionId: 'TASK_ID',
   2023-08-17T18:42:37.71+0000 [APP/PROC/WEB/0] OUT Description: 'DESCRIPTION',
   2023-08-17T18:42:37.71+0000 [APP/PROC/WEB/0] OUT CreatedBy: 'CREATED_BY',
   2023-08-17T18:42:37.71+0000 [APP/PROC/WEB/0] OUT Others: { 'Creation Date': 'CREATED_ON', Priority: 'PRIORITY' }
   2023-08-17T18:42:37.71+0000 [APP/PROC/WEB/0] OUT },

Br, Chanchal

AFK-Python commented 1 year ago

Hi Chanchal,

We suspect the root cause of this issue is happening inside of the S/4 HANA system.

Below is the logic of how the ABAP job would grab the approver ID and email address from S/4:

  1. Fetch the WI_ID (workflow task ID) from SWWWIHEAD table with the WI_RH_TASK = 'TS00800531' (task code of verify purchase order)
  2. Use Function Module SAP_WAPI_GET_WI_AGENTS with WI_ID to get the Agent (processor of verify purchase order task, is Approver) information. This Function Module will return the UserID of the Approver in S/4.
  3. Use Function Module BAPI_USER_GET_DETAIL with UserID to get the Email address of approver.

So in this case, since the USER_EMAIL is undefined, it could be because the Email Address of the Approver in the S/4HANA SU01 transaction is empty. Hopefully the steps above will resolve the issues you have been facing.

Best, Alex

ChanchalAgrawalMiku commented 1 year ago

Hi,

Thank you. I have now fixed the issue and the notification data is shown properly.

image

However when I am clicking the button "View More Details", then it is opening just a blank page.

image

When I execute "npm start" in frontend app, then it is throwing the following runtime error.

image

Br, Chanchal

AFK-Python commented 1 year ago

Hi Chanchal,

Have you defined each layer of the PO json configuration files? There should be three:

  1. PurchaseOrder.json
  2. PurchaseOrderItem.json
  3. PurchaseOrderTable.json

Each of these should be under config/public/frontend/simpleConfig/S4HanaCloud/IntegrationSuite/.

Best, Alex

ChanchalAgrawalMiku commented 1 year ago

Hi,

yes, I have defined all these 3 json files.

F12 console gives the following more details on error.

image image image image

Br, Chanchal

AFK-Python commented 1 year ago

Hi Chanchal,

There seems to be an extra import for some reason, process exists natively in reactjs. This seems to be causing your undefined error.

Best, Alex

ChanchalAgrawalMiku commented 1 year ago

Hi Alex,

I have now fixed the above process issue of frontend application.

But when I clicked "View More Details", it is throwing unauthorized errors to SAML url in backend application logs.

image

backend application logs:

2023-08-21T17:41:53.61+0000 [APP/PROC/WEB/0] OUT url: 'https://payg-free-xxxxx.authentication.eu10.hana.ondemand.com/oauth/token/alias/payg-free-xxxxx.aws-live-eu10',
    2023-08-21T17:41:53.61+0000 [APP/PROC/WEB/0] OUT statusCode: 401,
   2023-08-21T17:41:53.61+0000 [APP/PROC/WEB/0] OUT statusMessage: 'Unauthorized',
...
   2023-08-21T17:41:53.61+0000 [APP/PROC/WEB/0] OUT data: {
   2023-08-21T17:41:53.61+0000 [APP/PROC/WEB/0] OUT error: 'invalid_client',
   2023-08-21T17:41:53.61+0000 [APP/PROC/WEB/0] OUT error_description: 'Unauthorized grant type'
   2023-08-21T17:41:53.61+0000 [APP/PROC/WEB/0] OUT }   

Br, Chanchal

AFK-Python commented 1 year ago

Hi Chanchal,

A few things could be going wrong here. One problem could be missing user role collections in integration suite. Do you see data there after the IFlow url is consumed?

Another problem could be coming from S4 Hana Cloud. In order to configure OData APIs outside of S4 Hana Cloud, you need to creation a communication user and arrangement. This guide might help you get started in that regard.

Best, Alex

ChanchalAgrawalMiku commented 1 year ago

Hi Alex,

message is not reaching integration suite due to above unauthorized issue (bad credentials). Can you please suggest on how to add the missing user role collections in integration suite.

2023-08-23T19:46:51.788+0000 [APP/PROC/WEB/0] STDOUT socket: [TLSSocket],
2023-08-23T19:46:51.788+0000 [APP/PROC/WEB/0] STDOUT _header: 'POST /oauth/token/alias/xx.aws-live-eu10 HTTP/1.1\r\n' +
2023-08-23T19:46:51.788+0000 [APP/PROC/WEB/0] STDOUT 'Accept: application/json\r\n' +
2023-08-23T19:46:51.788+0000 [APP/PROC/WEB/0] STDOUT 'Content-Type: application/x-www-form-urlencoded\r\n' +
2023-08-23T19:46:51.788+0000 [APP/PROC/WEB/0] STDOUT 'User-Agent: axios/0.26.1\r\n' +
2023-08-23T19:46:51.788+0000 [APP/PROC/WEB/0] STDOUT 'Content-Length: 24308\r\n' +
2023-08-23T19:46:51.788+0000 [APP/PROC/WEB/0] STDOUT 'Host: payg-free-z04zlwfs.authentication.eu10.hana.ondemand.com\r\n' +
2023-08-23T19:46:51.788+0000 [APP/PROC/WEB/0] STDOUT 'Authorization: Basic xx' +
2023-08-23T19:46:51.788+0000 [APP/PROC/WEB/0] STDOUT 'Connection: close\r\n' +
2023-08-23T19:46:51.788+0000 [APP/PROC/WEB/0] STDOUT '\r\n',
2023-08-23T19:46:51.788+0000 [APP/PROC/WEB/0] STDOUT method: 'POST',
2023-08-23T19:46:51.788+0000 [APP/PROC/WEB/0] STDOUT path: '/oauth/token/alias/xxx.aws-live-eu10',
2023-08-23T19:46:51.788+0000 [APP/PROC/WEB/0] STDOUT _ended: true,
2023-08-23T19:46:51.788+0000 [APP/PROC/WEB/0] STDOUT res: [IncomingMessage],
2023-08-23T19:46:51.788+0000 [APP/PROC/WEB/0] STDOUT host: 'xxx.authentication.eu10.hana.ondemand.com',
2023-08-23T19:46:51.788+0000 [APP/PROC/WEB/0] STDOUT protocol: 'https:',
2023-08-23T19:46:51.788+0000 [APP/PROC/WEB/0] STDOUT [Symbol(corked)]: 0,
2023-08-23T19:46:51.788+0000 [APP/PROC/WEB/0] STDOUT [Symbol(kOutHeaders)]: [Object: null prototype],
2023-08-23T19:46:51.788+0000 [APP/PROC/WEB/0] STDOUT [Symbol(errored)]: null,
2023-08-23T19:46:51.788+0000 [APP/PROC/WEB/0] STDOUT [Symbol(kUniqueHeaders)]: null
2023-08-23T19:46:51.788+0000 [APP/PROC/WEB/0] STDOUT },
2023-08-23T19:46:51.788+0000 [APP/PROC/WEB/0] STDOUT data: { error: 'unauthorized', error_description: 'Bad credentials' }
2023-08-23T19:46:51.788+0000 [APP/PROC/WEB/0] STDOUT },
2023-08-23T19:46:51.788+0000 [APP/PROC/WEB/0] STDOUT isAxiosError: true,
2023-08-23T19:46:51.788+0000 [APP/PROC/WEB/0] STDOUT toJSON: [Function: toJSON]
2023-08-23T19:46:51.788+0000 [APP/PROC/WEB/0] STDOUT }

Thanks, Chanchal

AFK-Python commented 1 year ago

Hi Chanchal,

We suspect this is an issue in your backend .env file, as we were able to replicate the issue. The problem is that the client credentials from integration suite are not defined. The integration suite at the space level should be called integration-flow. This should have a service key attached to it, and that key should hold the information needed for client credentials that you need to add to your backend .env and push to CF.

You will need to configure these two values in your backend .env with the values from your service key:

iFlowClientId=<INTEGRATION_FLOW_CLIENT_ID>
iFlowClientSecret=<INTEGRATION_FLOW_CLIENT_SECRET>

You should be able to log both of these values in the S4 Hana Cloud integration suite auth router to verify that the credentials are correctly being passed in.

What you will want to potentially log: env.iFlowClientId and env.iFlowClientSecret.

Best, Alex

ChanchalAgrawalMiku commented 1 year ago

Hi Alex,

Thanks, I have now updated the .env file and issue is resolved. However message is not reaching integration suite (and not triggering integration flow) to getPurchaseOrder and getPurchaseOrderItem data.

"View more details" page is now loading properly but without any values in it.

image

2023-08-24T16:49:21.17+0000 [APP/PROC/WEB/0] OUT Inside get interface mapping for onprem
   2023-08-24T16:49:21.17+0000 [APP/PROC/WEB/0] OUT Interface config received for OnPrem:  {
   2023-08-24T16:49:21.17+0000 [APP/PROC/WEB/0] OUT PurchaseOrder: {
   2023-08-24T16:49:21.17+0000 [APP/PROC/WEB/0] OUT iFlowKeys: [ 'poNumber' ],
   2023-08-24T16:49:21.17+0000 [APP/PROC/WEB/0] OUT searchUrl: '/http/s4hana-onprem/SearchPurchaseOrders',
   2023-08-24T16:49:21.17+0000 [APP/PROC/WEB/0] OUT getUrl: '/http/s4hana-onprem/GetPurchaseOrder',
   2023-08-24T16:49:21.17+0000 [APP/PROC/WEB/0] OUT updateUrl: '/http/s4hana-onprem/UpdatePurchaseOrder',
   2023-08-24T16:49:21.17+0000 [APP/PROC/WEB/0] OUT searchFields: [ 'PurchaseOrder', 'CompanyCode', 'Supplier' ],
   2023-08-24T16:49:21.17+0000 [APP/PROC/WEB/0] OUT updateFields: [
   2023-08-24T16:49:21.17+0000 [APP/PROC/WEB/0] OUT 'PurchasingGroup',
   2023-08-24T16:49:21.17+0000 [APP/PROC/WEB/0] OUT 'PurchasingOrganization',
   2023-08-24T16:49:21.17+0000 [APP/PROC/WEB/0] OUT 'PurchasingProcessingStatus',
   2023-08-24T16:49:21.17+0000 [APP/PROC/WEB/0] OUT 'AddressName',
   2023-08-24T16:49:21.17+0000 [APP/PROC/WEB/0] OUT 'AddressPhoneNumber'
   2023-08-24T16:49:21.17+0000 [APP/PROC/WEB/0] OUT ]
   2023-08-24T16:49:21.17+0000 [APP/PROC/WEB/0] OUT },
   2023-08-24T16:49:21.17+0000 [APP/PROC/WEB/0] OUT PurchaseOrderItem: {
   2023-08-24T16:49:21.17+0000 [APP/PROC/WEB/0] OUT iFlowKeys: [ 'itemNumber' ],
   2023-08-24T16:49:21.17+0000 [APP/PROC/WEB/0] OUT searchUrl: '/http/s4hana-onprem/SearchPurchaseOrderItems',
   2023-08-24T16:49:21.17+0000 [APP/PROC/WEB/0] OUT getUrl: '/http/s4hana-onprem/GetPurchaseOrderItem',
   2023-08-24T16:49:21.17+0000 [APP/PROC/WEB/0] OUT searchFields: [ 'Material' ],
   2023-08-24T16:49:21.17+0000 [APP/PROC/WEB/0] OUT updatedFields: [ 'TaxJurisdiction' ],
   2023-08-24T16:49:21.17+0000 [APP/PROC/WEB/0] OUT valuehelpUrl: '/http/s4hana-onprem/valuehelp',
   2023-08-24T16:49:21.17+0000 [APP/PROC/WEB/0] OUT valueHelp: { url: '/MM_PUR_PO_MAINT_V2_SRV', mapping: [Array] }
   2023-08-24T16:49:21.17+0000 [APP/PROC/WEB/0] OUT }
   2023-08-24T16:49:21.17+0000 [APP/PROC/WEB/0] OUT }
   2023-08-24T16:49:21.17+0000 [APP/PROC/WEB/0] OUT Teams token in getAzureAdAccessTokenForBtpSamlAssertion xx.xx
   2023-08-24T16:49:21.17+0000 [APP/PROC/WEB/0] OUT App details: XX XX
   2023-08-24T16:49:21.99+0000 [APP/PROC/WEB/0] OUT error
   2023-08-24T16:49:21.99+0000 [APP/PROC/WEB/0] OUT {"component_type":"application","component_id":"XX","component_name":"bridge-framework-backend",xx}
   2023-08-24T16:49:21.99+0000 [RTR/3] OUT bridge-framework-backend.cfapps.eu10-004.hana.ondemand.com - [2023-08-24T16:49:21.165147957Z] "GET /gateway/S4HanaOnPrem/IntegrationSuite/PurchaseOrder/4500000036 HTTP/2.0" 200 0 9030 "https://bridge-framework-frontend.cfapps.eu10-004.hana.ondemand.com/" 
   2023-08-24T16:49:22.06+0000 [APP/PROC/WEB/0] OUT Inside get interface mapping for onprem
    2023-08-24T16:49:22.06+0000 [APP/PROC/WEB/0] OUT Interface config received for OnPrem:  {
   2023-08-24T16:49:22.06+0000 [APP/PROC/WEB/0] OUT PurchaseOrder: {
   2023-08-24T16:49:22.06+0000 [APP/PROC/WEB/0] OUT iFlowKeys: [ 'poNumber' ],
   2023-08-24T16:49:22.06+0000 [APP/PROC/WEB/0] OUT searchUrl: '/http/s4hana-onprem/SearchPurchaseOrders',
   2023-08-24T16:49:22.06+0000 [APP/PROC/WEB/0] OUT getUrl: '/http/s4hana-onprem/GetPurchaseOrder',
   2023-08-24T16:49:22.06+0000 [APP/PROC/WEB/0] OUT updateUrl: '/http/s4hana-onprem/UpdatePurchaseOrder',
   2023-08-24T16:49:22.06+0000 [APP/PROC/WEB/0] OUT searchFields: [ 'PurchaseOrder', 'CompanyCode', 'Supplier' ],
   2023-08-24T16:49:22.06+0000 [APP/PROC/WEB/0] OUT updateFields: [
   2023-08-24T16:49:22.06+0000 [APP/PROC/WEB/0] OUT 'PurchasingGroup',
   2023-08-24T16:49:22.06+0000 [APP/PROC/WEB/0] OUT 'PurchasingOrganization',
   2023-08-24T16:49:22.06+0000 [APP/PROC/WEB/0] OUT 'PurchasingProcessingStatus',
   2023-08-24T16:49:22.06+0000 [APP/PROC/WEB/0] OUT 'AddressName',
   2023-08-24T16:49:22.06+0000 [APP/PROC/WEB/0] OUT 'AddressPhoneNumber'
   2023-08-24T16:49:22.06+0000 [APP/PROC/WEB/0] OUT ]

Br, Chanchal

ChanchalAgrawalMiku commented 1 year ago

Hi,

Also when I am trying to fetch the PurchaseOrders from S/4HANA on-premise via Destination, then it is not bringing any data.

Do we need maintain the destination parameters in .env environment variables?

backend Logs:

 "message":"Attempting to retrieve destination from environment variable.","msg":"Attempting to retrieve destination from environment variable.",
   "message":"No environment variable set.","msg":"No environment variable set.",
   "message":"Attempting to retrieve destination from service binding.","msg":"Attempting to retrieve destination from service binding.",
   ,"message":"Could not retrieve destination from service binding. If you are not using SAP Extension Factory, this information probably does not concern you. Service of type destination is not supported! Consider providing your own transformation function when calling destinationForServiceBinding, like this:\n  destinationServiceForBinding(yourServiceName, { serviceBindingToDestination: yourTransformationFunction });","msg":"Could not retrieve destination from service binding. If you are not using SAP Extension Factory, this information probably does not concern you. Service of type destination is not supported! Consider providing your own transformation function when calling destinationForServiceBinding, like this:\n  destinationServiceForBinding(yourServiceName, { serviceBindingToDestination: yourTransformationFunction });","timestamp":"2023-08-25T12:23:48.422Z","written_at":"2023-08-25T12:23:48.422Z","written_ts":1692966228422}
  "message":"Attempting to retrieve destination from destination service.","msg":"Attempting to retrieve destination from destination service.",

Br, Chanchal

AFK-Python commented 1 year ago

Hi Chanchal,

Regarding the first question on integration suite, the IFlowUrl doesn't seem to be set in your backend. The integration suite artifact endpoint host name should be set to the value of the iFlowUrl in the backend .env file.

Additionally, in the objectMappingConfig.json there are three keys under the SystemName that must be configured: searchUrl, getUrl, and updateUrl.

Firstly, ensure that the integration suite is setup to get purchase order data by ID - this means an IFlow artifact must be used to fetch the Purchase Order by Purchase Order number, and accept the purchase order number as the input parameter in the iFlow artifact. This input parameter would then be used as the value of iFlowKeys in the objectMappingConfig.json. The URI of the GetPurchaseOrderByID iFlow artifact should be the value of the getUrl.

The same idea applies for the searchUrl and updateUrl, with a couple of key additions. For the searchUrl, you need to mention the filed name of the Business Object in the searchFields that you would like to perform searching on. For the updateUrl, you need to mention the filed name of the Business Object in the updateFields that you would like to perform the updates on.

For the destination value not found: the destination name in the S4HanaOnPrem -> Destination -> PurchaseOrder -> destinationName must be in the Config Server -> backend -> objectMappingConfig.json file.

Hope that helps.

Best, Alex

ChanchalAgrawalMiku commented 1 year ago

Hi Alex,

Thank you. I have now fixed the issue and data is populated properly :)

image

However when I click approve then it is not approving the purchase order in S/4HANA. When I checked the backend logs, it is failing with HTTP 500 error. What should be the value of the "InstanceID" for approval ?

Backend Logs:

path: 'http://xxx:8443/sap/opu/odata/IWPGW/TASKPROCESSING;mo;v=2/Decision?sap-client=313&SAP__Origin=%27LOCAL_TGW%27&InstanceID=%27000000008066%27&DecisionKey=%270001%27',
bridge-framework-backend.cfapps.eu10-x.hana.ondemand.com - [2023-08-28T15:09:26.197692098Z] "POST /gateway/S4HanaOnPrem/Destination/PurchaseOrder/4500000055?review=true HTTP/2.0" 500 50 86
statusCode: 500,
statusMessage: 'Internal Server Error',

Br, Chanchal

ChanchalAgrawalMiku commented 1 year ago

Thank you for your support. I have now fixed this issue as well and end-to-end working perfect as desired :)