All Blogs in this Series –

AI Powered Invoice Management with SAP RAP and ABAP on Cloud

AI Powered Invoice Management with SAP RAP and ABAP on Cloud – Part 1

AI Powered Invoice Management with SAP RAP and ABAP on Cloud – Part 2

AI Powered Invoice Management with SAP RAP and ABAP on Cloud – Part 3

 

If you want to know the reference of this blog, please go through the Part 1 & Part 2 sections of this AI Powered Invoice Management Series.

This is going to be the last part of the AI Powered Invoice Management Series. What we are focusing here is –

  1. Creating a Unmanaged scenario
  2. Creation of a ABAP Workflow
  3. Creation of a NodeJS based Wrapper on top of the ABAP Unmanaged API

 

Process Flow

On-premise developments ( Create RAP Unmanaged API )

Create a custom table –

 

Create CDS Entity

@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Interface of WF Trigger'
define root view entity Z_I_INV_PO_WF 
 as select from 
// zinv_po_status 
 ekko left outer join 
 zinv_po_status on ekko.ebeln = zinv_po_status.ebeln 
{
// key ekko.ebeln,
 key zinv_po_status.ebeln,
 zinv_po_status.amount,
 zinv_po_status.status 
}

 

Create a Projection view –

@EndUserText.label: 'Peojection view for INV PO WF'
@AccessControl.authorizationCheck: #NOT_REQUIRED
define root view entity Z_P_INV_PO_WF 
provider contract transactional_query
as projection on Z_I_INV_PO_WF {
 key ebeln,
 amount,
 status 
}

 

Create Behavior Definition –

unmanaged
implementation in class zbp_i_inv_po_wf unique;
define behavior for Z_I_INV_PO_WF 
{
 create;
} 
projection;
//strict;
define behavior for Z_P_INV_PO_WF //alias <alias_name>
{
 use create;
// use update;
// use delete;
}

 

Implement the Behavior class

CLASS lhc_z_i_inv_po_wf DEFINITION INHERITING FROM 
cl_abap_behavior_handler.
 PRIVATE SECTION.
 METHODS create FOR MODIFY
 IMPORTING entities FOR CREATE z_i_inv_po_wf.
 METHODS read FOR READ
 IMPORTING keys FOR READ z_i_inv_po_wf RESULT result.
ENDCLASS.
CLASS lhc_z_i_inv_po_wf IMPLEMENTATION.
 METHOD create.
 DATA: ls_line TYPE zinv_po_status,
 lt_lines TYPE TABLE OF zinv_po_status.
 LOOP AT entities ASSIGNING FIELD-SYMBOL(<ls_entity>).
 ls_line = CORRESPONDING #( <ls_entity> ).
 APPEND ls_line TO lt_lines.
 DATA : lv_objectkey TYPE swr_struct-object_key.
 DATA: lt_input_container TYPE TABLE OF swr_cont,
 lv_subrc TYPE sy-subrc,
 lv_value TYPE swe_evtid,
 lt_msglns TYPE TABLE OF swr_messag,
 lt_msgstr TYPE TABLE OF swr_mstruc.
 lv_objectkey = ls_line-ebeln.
 lt_input_container = VALUE #( ( element = 'PurchasingDocument'
value = ls_line-ebeln ) ( element = 'TargetValue' value = ls_lineamount ) ).
 CALL FUNCTION 'SAP_WAPI_CREATE_EVENT' STARTING NEW TASK 
lv_objectkey 
 EXPORTING
 object_type = 'ZINV_PUORD'
 object_key = lv_objectkey 
 event = 'PROCESS_PAY_FOR_INV'
 TABLES
 input_container = lt_input_container 
 message_lines = lt_msglns 
 message_struct = lt_msgstr.
 ENDLOOP.
 zcl_inv_payment=>update_table( it_table = lt_lines ).
 ENDMETHOD.
 METHOD read.
 ENDMETHOD.
ENDCLASS.
CLASS lsc_z_i_inv_po_wf DEFINITION INHERITING FROM 
cl_abap_behavior_saver.
 PROTECTED SECTION.
 METHODS finalize REDEFINITION.
 METHODS check_before_save REDEFINITION.
 METHODS save REDEFINITION.
 METHODS cleanup REDEFINITION.
 METHODS cleanup_finalize REDEFINITION.
ENDCLASS.
CLASS lsc_z_i_inv_po_wf IMPLEMENTATION.
 METHOD finalize.
 ENDMETHOD.
 METHOD check_before_save.
 ENDMETHOD.
 METHOD save.
 ENDMETHOD.
 METHOD cleanup.
 ENDMETHOD.
 METHOD cleanup_finalize.
 ENDMETHOD.
ENDCLASS.

 

On-premise developments ( Workflow Developments )

Create a basic workflow –

 

Now implement global variables –

 

Add decisions Approve and Reject in the Workflow

Configure the bindings

 

Create Events in SWo1 and set the parameters –

 

Here are the parameter lists of the workflow –

 

SAP CF NodeJS Express server to trigger the Workflow

Create a NPM package and create index.js

var express = require('express'); 
var app = express(); 
var PORT = 8080; 
var lib = require('./lib'); 
app.use(express.json()); 
app.use(express.urlencoded({ extended: true })); 
app.post('/trigger_wf', async function (req, res) { 
 await lib.trigger_wf(req, res); 
}); 
app.get('/', async function (req, res) { 
 await lib.base(req, res); 
}); 
app.listen(PORT, function (err) { 
 if (err) console.log(err); 
 console.log("Server listening on PORT", PORT); 
}); 

 

Now create the lib.js file

const SapCfAxios = require('sap-cf-axios').default; 
const xsenv = require('@sap/xsenv'); 
module.exports = { 
 base: async function base(req, res) { 
 res.send(JSON.stringify({ 'uri': '/trigger_wf' })); 
 }, 
 trigger_wf: async function trigger_wf(req, res) { 
 var custurl = process.env['MURL']; 
 console.log('I am here'); 
 // var data = req.body;
 console.log('--------------------') 
 console.log(req.body); 
 var data = req.body; 
 var post_body = { 
 "ebeln": data.ebeln, 
 "amount": data.amount, 
 "status": data.status
 } 
 console.log(post_body); 
 try { 
 console.log('--------------------') 
 const axios_DUMMY_GET = SapCfAxios('DUMMY_GET'); 
 const response = await axios_DUMMY_GET({ 
 method: 'post', 
 url: custurl, 
 headers:{ 
 "X-Requested-With" : "X"
 }, 
 data: post_body
 }); 
 console.log('--------------------') 
 console.log(JSON.stringify(response.data.d)) 
 res.json({ "STATUS": "Post Successful" }); 
 } catch (error) { 
 console.log(JSON.stringify(error)); 
 res.json({ "STATUS": "Error in Post", "MES":
JSON.stringify(error) }); 
 } 
 } 
}

and use manifest.yml file to deploy your nodejs to cloud foundry environment

 

Note – Here sap-cf-axios is used to create a secure communication tunnel to call the on-premise destination through the SAP BTP destination and Cloud Connectors.

Thanks for having patience reading out the blog till the end. Hope to hear from you….

 

Sara Sampaio

Sara Sampaio

Author Since: March 10, 2022

0 0 votes
Article Rating
Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x