Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
sabarna17
Contributor

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....

 
2 Comments
Labels in this area