In BTP Use JS SAP Cloud SDK create material document in S/4 Hana Cloud

In S/4 Hana Cloud side by side extension , we need to develope backend to create material document in S/4 Hana cloud . In this case we use nodejs .  If we use SAP Cloud SDK , it will improve our developement efficiency greatly . Today I want to demo how to create material document in S/4 Hana Cloud with SAP Cloud SDK in nodejs .

In api hub in the following linkage , we can check cloud sdk for material document .

SAP API Business Hub

Code snippy:

package.json

{ "name": "capdemo23-srv", "engines": { "node": "14.x" }, "dependencies": { "@sap-cloud-sdk/core": "latest", "@sap/cloud-sdk-vdm-material-document-service": "latest", "@sap-cloud-sdk/temporal-de-serializers": "latest", "@sap/hana-client": "^2.12.22", "@sap/xsenv": "latest", "@sap/xssec": "latest", "body-parser": "latest", "cors": "latest", "express": "latest", "passport": "latest" }, "scripts": { "start": "node server.js" }
}

server.js

const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const cors = require('cors');
const { temporalDeSerializersV2 } = require('@sap-cloud-sdk/temporal-de-serializers'); const xsenv = require('@sap/xsenv');
xsenv.loadEnv();
const services = xsenv.getServices({ uaa: { tag: 'xsuaa' }
}); const xssec = require('@sap/xssec');
const passport = require('passport');
passport.use('JWT', new xssec.JWTStrategy(services.uaa));
app.use(passport.initialize());
app.use(passport.authenticate('JWT', { session: false
})); app.use(bodyParser.json());
app.use(cors()); const { retrieveJwt } = require('@sap-cloud-sdk/core');
const { desc } = require('@sap-cloud-sdk/core'); const{ materialDocumentService } =require('@sap/cloud-sdk-vdm-material-document-service');
const { json } = require('body-parser');
const{materialDocumentHeaderApi,materialDocumentItemApi}=materialDocumentService(temporalDeSerializersV2); function postMaterialDoc(req){ // console.log(req.body); let docs = new Array(); req.body.to_MaterialDocumentItem.forEach(function(e){ let doc = materialDocumentItemApi.entityBuilder() .material(e.Material).plant(e.Plant).storageLocation(e.StorageLocation) .goodsMovementType(e.GoodsMovementType).purchaseOrder(e.PurchaseOrder) .purchaseOrderItem(e.PurchaseOrderItem).goodsMovementRefDocType(e.GoodsMovementRefDocType) .entryUnit(e.EntryUnit).quantityInEntryUnit(e.QuantityInEntryUnit).build(); docs.push(doc); }); const materialDoc = materialDocumentHeaderApi.entityBuilder().postingDate(req.body.PostingDate).goodsMovementCode(req.body.GoodsMovementCode).toMaterialDocumentItem(docs).build(); console.log(materialDoc); return materialDocumentHeaderApi.requestBuilder().create(materialDoc).execute({ destinationName: 'O5P' , jwt: retrieveJwt(req) }); } app.get('/srv/purchaseorders',function(req,res){ getPurchaseOrders(req) .then( result => { res.status(200).json(result); }).catch( err => { res.status(500).send(err)}); }); const port = process.env.PORT || 5001;
app.listen(port, function () { console.info('Listening on http://localhost:' + port);
});

mta.yml

ID: capdemo23
_schema-version: "3.1"
version: 0.0.1 parameters: enable-parallel-deployments: true modules: - name: capdemo23-srv type: nodejs path: srv parameters: disk-quota: 512M memory: 256M provides: - name: srv_api properties: url: ${default-url} requires: - name: capdemo23-uaa - name: capdemo23-dest - name: capdemo23-app type: html5 path: app parameters: disk-quota: 512M memory: 256M requires: - name: capdemo23-uaa - name: srv_api group: destinations properties: name: srv url: ~{url} forwardAuthToken: true
resources: - name: capdemo23-uaa type: org.cloudfoundry.managed-service parameters: path: ./xs-security.json service-plan: application service: xsuaa - name: capdemo23-dest type: org.cloudfoundry.managed-service parameters: service: destination service-plan: lite config: init_data: instance: existing_destinations_policy: ignore destinations: - Name: capdemo23-s4hc-api Description: S/4HANA Cloud URL: https://sandbox.api.sap.com/s4hanacloud Type: HTTP ProxyType: Internet Authentication: NoAuthentication URL.headers.APIKey: <SetValueInCockpit> URL.headers.Application-Interface-Key: <SetValueInCockpit>

xs-security.json

{ "xsappname": "capdemo23", "tenant-mode": "dedicated", "scopes": [ { "name": "$XSAPPNAME.User", "description": "User" }, { "name": "$XSAPPNAME.Admin", "description": "Admin" } ], "role-templates": [ { "name": "User", "description": "User", "scope-references": [ "$XSAPPNAME.User" ] }, { "name": "Admin", "description": "Admin", "scope-references": [ "$XSAPPNAME.Admin" ] } ], "role-collections": [ { "name": "capdemo23_User", "description": "capdemo23 User", "role-template-references": [ "$XSAPPNAME.User" ] }, { "name": "capdemo23_Admin", "description": "capdemo23 Admin", "role-template-references": [ "$XSAPPNAME.Admin" ] } ]
}

Build the project with :

mbt build

deploy the application to BTP cloud foundry with the following command, after you have login in BTP with cf login

cf deploy  the_generated_mta_file.mtar

Create communication arrangement in s/4 hana cloud:

Create  destination in BTP:

Test the deployed application with postman

get the deployed url and oauth information

The end .

Best Regards!

Jacky Liu